0

I've a class:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

In the User Table:

Id    Name    
1     Tommy
2     John

I create an object:

Person P = new Person { Name = "Test", UserId = 1 };

I insert the Person object into the database:

db.Persons.Add(P);
db.SaveChanges();
var user = P.User;

The problem is if I try to access P.User it contains null. Other properties of P are populated properly.

Why?

Henk Mollema
  • 44,194
  • 12
  • 93
  • 104
hendrixchord
  • 4,662
  • 4
  • 25
  • 39
  • Don't use ALLCAPS in titles, please. – jmoerdyk Nov 06 '13 at 17:56
  • Did you set user? It looks like you create a Person but don't associate the person with a user - is the UserId supposed to do that? You've also got a lazy loaded (virtual) nav property, it might be worth profiling the SQL server to see what it tries to load when you access the property – Charleh Nov 06 '13 at 18:00
  • Yes the UserId will do the association – hendrixchord Nov 06 '13 at 18:03
  • possible duplicate of [Entity Framework: I set the foreign key, SaveChanges then access the navigation property, but it doesn't load the related entity. Why not?](http://stackoverflow.com/questions/15552891/entity-framework-i-set-the-foreign-key-savechanges-then-access-the-navigation) – Colin Nov 07 '13 at 10:09
  • And the solution I now use with the repository pattern: http://stackoverflow.com/questions/16736143/how-to-ensure-proxies-are-created-when-using-the-repository-pattern-with-entity – Colin Nov 07 '13 at 10:10

3 Answers3

2

You should create the Person as follows:

Person p = db.Persons.Create();
p.Name = "Test";
p.UserId = 1;

The difference is that the Person is now created as a dynamic proxy, which means that it is capable of lazy loading. Once it is attached to the context (by db.Persons.Add) you can access the associated User.

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • I'm using repository & unit of work pattern, could you tell me how I can incorporate this? – hendrixchord Nov 07 '13 at 04:06
  • Where have you got the `new Person` call now? It should be possible to replace that, I guess, since the repo should have a `DbContext` or a `DbSet`. – Gert Arnold Nov 07 '13 at 08:00
0

You should mark the UserId property as a foreign key like:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    [ForeignKey("User")]
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

Like that, the entity framework will know that your UserId property is supposed to belong to the User property.

moritzpflaum
  • 729
  • 4
  • 10
0

I think you need to execute a new query for the person. An Entity Framework insert query will only return the id of the new object by using SCOPE_IDENTITY(), so the related objects aren't loaded. What if you do this:

var newPerson = db.Persons.Find(P.Id);
var user = newPerson.User;
Henk Mollema
  • 44,194
  • 12
  • 93
  • 104