I have a problem about accessing third level navigation properties in my context. I have searched a lot for two days but could not find any issue close to mine. So I thought that I have a logical mistake about my approach.
I use the MVC template project. Model classes and context are below.
public partial class Tests
{
[Key]
public int TestID { get; set; }
public string TestName { get; set; }
public List<UserTests> UserTests { get; set; }
}
public partial class UserTests
{
[Key, Column(Order=1)]
public string UserID { get; set; }
[Key, Column(Order = 2)]
public int TestID { get; set; }
public Nullable<double> TestValue { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public Tests Tests { get; set; }
}
public partial class UserDetail
{
[Key]
public int ID { get; set; }
public string UserID { get; set; }
public string Name { get; set; }
public ApplicationUser ApplicationUser { get; set; }
}
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public List<UserTests> UserTests { get; set; }
public List<UserDetail> UserDetails { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public IDbSet<Tests> Tests { get; set; }
public IDbSet<UserDetail> UserDetails { get; set; }
public IDbSet<UserTests> UserTests { get; set; }
}
I try to reach UserDetails
properties from UserTests
. But I can't find Select
method inside the Include
method clicking dot after ApplicationUser
.
public ActionResult Index()
{
var userTests = db.UserTests.Include(u => u.Tests).Include(y => y.ApplicationUser.UserDetails);
return View(userTest.ToList());
}
This is the index view.
@model IEnumerable<WebApplication6.Models.UserTests>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.ApplicationUser.Email)
</th>
<th>
@Html.DisplayNameFor(model => model.Tests.TestName)
</th>
<th>
@Html.DisplayNameFor(model => model.TestValue)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<th>
@Html.DisplayFor(modelItem => item.ApplicationUser.Email)
</th>
<td>
@Html.DisplayFor(modelItem => item.Tests.TestName)
</td>
<td>
@Html.DisplayFor(modelItem => item.TestValue)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
I want the view to display ApplicationUser's Name instead of Email which is in the UserDetails
model class. So I want to type a Razor code like below but I can't. There is no Name
property after UserDetails
@Html.DisplayNameFor(model => model.ApplicationUser.UserDetails.Name)
Select
method there?UserDetails
properties from UserTests
with include or another ef method?UserTests
, ApplicationUser
and UserDetails
properties?UserDetails.Name
property instead of ApplicationUser.Email
property?This is the Include
you're looking for:
db.UserTests.Include(x => x.ApplicationUser.UserDetails);