I'm having trouble pulling a ApplicationUser object in a query to the DbContext.
Here is my Foo model
public class Foo
{
public int Id { get; set; }
public string Title { get; set; }
public ApplicationUser Creator { get; set; }
}
Inside of my Foo controller in the edit action I want to check that the User requesting the edit is the Creator.
//ApplicationDbContext inherits IdentityDbContext
private ApplicationDbContext appDb { get; set; }
...
public async Task<ActionResult> Edit(int? id)
{
Foo target = appDb.Foos.First(o => o.Id == id);
if (target == null)
{
return HttpNotFound();
}
if (target.Creator.Id != User.Identity.GetUserId())
{
ViewBag.Error = "Permission denied.";
return Redirect(Request.UrlReferrer.ToString());
}
return View(target);
}
The problem is that for some reason target.Creator returns null, although all Foo have a Creator object referenced. In the same controller, in the details action it gets pulled just fine:
var entry = appDb.Foos.Where(f=>f.Id == id)
.Select(foo => new FooViewModel()
{
Id = foo.Id,
Title = foo.Title,
CreatorId = foo.Creator.Id,
CreatorName = foo.Creator.FirstName,
}).FirstOrDefaultAsync();
What am I missing? What is so different about trying to access foo.Creator inside of the Display query than trying to access it directly on a Foo object? I thought EF would have queried for foo.Creator when I requested the Foo itself.
Should I change foo.Creator to store foo.CreatorId instead?
Thanks.
The navigation properties are not feched by default. If you need them, eager load them using .Include():
Foo target = appDb.Foos.First(o => o.Id == id).Include(f => f.Creator);
Your code will not work at all: if you try to find the first element, with .First() and it doesn't exist, you'll get an exception. I.e, your code will never hit if (target == null).
You should use .FirstOrDefault(), or better thant that, Find().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With