6

I have a lookup table and a data table in my db. I'll use gender and person for an example. So let's say the gender table looks like so:

Id         Code
1          Male
2          Female

and the person table looks like so:

Id         Name             GenderId
1          Bob              1
2          Jane             2

I've modelled both tables in EF code first like so:

public class Gender
{
    public int Id {get;set;}
    public string Code {get;set;}
}

public class Person
{
    public int Id {get;set;}
    public string Name {get;set;}
    public int GenderId {get;set;}

    public virtual Gender {get;set;}
}

If I read a person already in the DB then I can access person.Gender.Code without a problem. If I do this:

var person = new Person
             {
                 Name = "Bob",
                 GenderId = 1,
             };

context.People.Add(person);
context.SaveChanges();

var code = person.Gender.Code;

Then it will save correctly but will fail on the last line as gender is null. If I then open a new context and load the saved entity then the last line works fine. Is there a way that I can access gender directly after a save as if I just loaded the entity from the DB?

2
  • The last sentence is unfinished, could you correct it? Commented Jun 14, 2012 at 6:28
  • Sorry about that, it didn't save the first time and when I came back to the page it must not have loaded the whole thing. Commented Jun 14, 2012 at 6:35

1 Answer 1

11

Your problem is that when you use new Person() it will just create a POCO object which doesn't know how to get the it's Gender property. So to make the lazy loading work you need proxies.

You can create your person as a proxy with DbSet.Create():

var person = context.People.Create();
person.Name = "Bob";
person.GenderId = 1;

context.People.Add(person);
context.SaveChanges();
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you!! The first piece of code worked great. The second one would have been preferable but it did not work. It seems that it just spits out the cached version of the person which doesn't have lazy loading enabled.
Yeah it seems Find() won't return a proxy... Can you try it with context.People.Single(p => p.Id == person.Id) ?
Single also doesn't work. However if you call context.People.Load(); before the Find or Single it works, but it reloads the collection into the context.So I think you should use the Create to generate proxies so I removed the Find related part of my answer.
It does the same thing. Straight out the cache and not a proxy.
Awesome! I'll use the .Create(). Thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.