J86
J86

Reputation: 15237

Create with ViewModel that has two related entities

I have the properties for two entities in a ViewModel. The two entities are both related to one another, so for example, User and Posts. Each User can have multiple Posts, and Many Posts can belong to a single user (one-to-many).

The aim from my ViewModel is to allow the addition of a User and a Post on the same form. So my ViewModel looks something like this:

public class CreateVM
{
    [Required, MaxLength(50)]
    public string Username { get; set; }

    [Required, MaxLength(500), MinLength(50)]
    public string PostBody { get; set; }

    // etc with some other related properties
}

In my Controller on the Create Method I have something like this:

[HttpPost]
public ActionResult Create(CreateVM vm)
{
    if (ModelState.IsValid)
    {
            User u = new User()
            {
                Username = vm.Username,
                // etc populate properties
            };

            Post p = new Post()
            {
                Body = vm.PostBody,
                // etc populating properties
            };

            p.User = u; // Assigning the new user to the post.

            XContext.Posts.Add(p);

            XContext.SaveChanges();
    }
}

It all looks fine when I walk through it through the Debugger, but when I try to view the post, its User relationship is null!

I also tried

u.Posts.Add(p);

UPDATE:

My Post class code is as follows:

public class Post
{
    [Key]
    public int Id { get; set; }
    [Required, MaxLength(500)]
    public string Body { get; set; }
    public int Likes { get; set; }
    [Required]
    public bool isApproved { get; set; }
    [Required]
    public DateTime CreatedOn { get; set; }
    [Required]
    public User User { get; set; }
}

But that also did not work. What am I doing wrong?

Upvotes: 1

Views: 343

Answers (1)

Eranga
Eranga

Reputation: 32437

Problem is that EF can not lazy load the User property because you haven't made it virtual.

public class Post
{
    [Key]
    public int Id { get; set; }
    [Required, MaxLength(500)]
    public string Body { get; set; }
    public int Likes { get; set; }
    [Required]
    public bool isApproved { get; set; }
    [Required]
    public DateTime CreatedOn { get; set; }
    [Required]
    public virtual User User { get; set; }
}

If you know beforehand that you are going to access the User property of the post you should eager load the User related to the post.

context.Posts.Include("User").Where(/* condition*/);

Upvotes: 1

Related Questions