问题
I am having a simple ViewModel which have something like this...
ViewModel
public class UserPostCommentViewModel
{
public virtual List<Comment> Comment { get; set; }
public virtual User User { get; set; }
public virtual Post Post { get; set; }
}
so that i can return a view which has 1 Post with the details 1 User details and Many Comments submitted by users....
POST
[Key]
[ScaffoldColumn(true)]
public int PostID { get; set; }
[Required(ErrorMessage="Required")]
[StringLength(250)]
public string Title { get; set; }
[Required(ErrorMessage="Required")]
[DataType(DataType.MultilineText)]
public string Body { get; set; }
[DataType(DataType.Date)]
public DateTime DateCreated { get; set; }
[DataType(DataType.Date)]
public DateTime DateModified { get; set; }
[ScaffoldColumn(false)]
public int UserID { get; set; }
[ScaffoldColumn(false)]
public int? TagID { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual User Users { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
Comment
[Key]
[ScaffoldColumn(true)]
public int CommentID { get; set; }
[DisplayName("Your Comment")]
[DataType(DataType.MultilineText)]
public string Body { get; set; }
[DataType(DataType.Date)]
[ScaffoldColumn(true)]
public DateTime DateCreated { get; set; }
[ScaffoldColumn(true)]
public int PostID { get; set; }
[ScaffoldColumn(true)]
public int UserID { get; set; }
public User User { get; set; }
public Post Posts { get; set; }
USer
[ScaffoldColumn(true)]
[Key]
public int UserID { get; set; }
[StringLength(15)]
[DisplayName("First Name")]
[Required(ErrorMessage="First Name is Required")]
public string FirstName { get; set; }
[StringLength(15)]
[DisplayName("Last Name")]
[Required(ErrorMessage = "Last Name is Required")]
public string LastName { get; set; }
[DataType(DataType.EmailAddress,ErrorMessage="please enter valid email")]
[DisplayName("Email Address")]
[Required(ErrorMessage = "Email is Required")]
[Remote("CheckUniqueEmail","User",ErrorMessage="An account with this email address already exists.")]
public string Email { get; set; }
[DataType(DataType.Password)]
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[DataType(DataType.Date)]
[ScaffoldColumn(true)]
public DateTime JoiningDate { get; set; }
[DataType(DataType.Date)]
[ScaffoldColumn(true)]
public DateTime? LastActivityDate { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
i have a StronglyTyped View with the ViewModel so that i can return all the three model properties in one view...
BUT :( i want to show the userName instead of userID in front of the each comment for that particular post. so i am using ICollection comments in the viewmodel so that i can return collection of the comments. and when i try to access the userName property like this @Model.Comments.User.LastName // OR Email // OR FirstName .. i am getting the compilation error. and i cant use like this because its a collection type ...
how can i retrieve the userName from the comments entity using the userID which is available in comments..
please help...
Got it all working by adding in the partial view..
_Comments Partial View..
in my partial view i have added like this...
========================
@{
ContextRepository db = new ContextRepository();
var userID = Model.UserID;
var userName = db.EUser.Find(userID).FirstName;
}
回答1:
You can create a partial view to display the comment and call that inside a loop in the main view.
Post Details view
@model UserPostCommentViewModel
@{
ViewBag.Title = "Post";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@foreach (Comment comment in Model.Comments)
{
@Html.Partial("_Comment", comment);
}
_Comment partial view
@model Comment
<div class="comment">
<div class="desc">@Model.Body</div>
<div class="submitted-by">@Model.User.LastName</div>
</div>
Model issues
You need to make the navigational properties virtual to be lazy loaded.
public class Comment
{
//other properties
public virtual User User { get; set; }
public virtual Post Posts { get; set; }
}
If you are going to access these navigational properties then you need to eager load them. Otherwise you will run into Select n+1 problem. Use the Include method to eager load properties
var post = db.Posts.Include(p => Comments)
.Include(p => p.Comments.Select(c => c.User))
.Where(p => p.PostID == 1).Single();
来源:https://stackoverflow.com/questions/7409195/error-while-accessing-the-navigation-property-in-ef-code-first