Error while accessing the Navigation Property in EF Code First

早过忘川 提交于 2020-01-07 02:16:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!