2

I'm using EF Code First with a pre-existing database.

Two objects:

public Foo
{
    public int FooId {get;set;}
}

public Bar
{
    public int BarId {get;set;}
    public virtual Foo Foo {get;set;}
}

Both FooId and BarId are primary keys in the database, and the Bar table has a column FooId which is a foreign key pointing at the Foo table.

When I select a Bar, Foo is a null reference. I would have thought EF would have automatically pulled the two of them together, but perhaps I'm missing something?

Database mappings:

public class EFCodeFirst : DbContext
{
    public EFCodeFirst()
    {
        this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["AlternateString"].ConnectionString;
    }

    public DBSet<Foo> Foos {get;set;}
    public DBSet<Bar> Bars {get;set;}

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        modelBuilder.IncludeMetadataInDatabase = false;
        modelBuilder.Entity<Foo>().MapSingleType().ToTable("Foo");
        modelBuilder.Entity<Bar>().MapSingleType().ToTable("Bar");
    }
}
2
  • Can you also post your code first mapping? What happens if you call the query with Include("Foo")? Commented Nov 19, 2010 at 10:46
  • If I Include("Foo") it works. Commented Nov 20, 2010 at 2:08

2 Answers 2

2

If your expectation of Foo should not be null is coming from the fact that you make it virtual on Bar object, then that's not the case. By make them virtual, you just opt in to EF lazy loading and it will be null up until to the point that you explicitly ask for it by accessing it on Bar object. Other than that, if you want it to be populated upfront you would have to eager load it with Include method.

To explicitly disable lazy loading you can use the following code, even though you don't need it since you can just remove the virtual keyword from your navigation properties and lazy loading would be gone.

public EFCodeFirst()
{        
    this.ObjectContext.ContextOptions.LazyLoadingEnabled = false;
}

Internally, DbContext uses a protected ObjectContext that you can also use inside your inherited DbContext class (e.g. EFCodeFirst).

Sign up to request clarification or add additional context in comments.

4 Comments

But either way it should still resolve, correct? Either with an early or later call to the DB.
I also cannot figure when to disable lazy loading. None of the objects have a reference to ContextOptions.LazyLoadingEnabled.
Yes that is correct and it does work. You need to show us the code that does not work.
I also edit my answer to show how to change the value of ContextOptions.LazyLoadingEnabled
0

You are missing a line in the Foo class, that Foo contains a collection of Bar.

2 Comments

There is currently no need to access the Bar objects from the parent Foo.
Yes, but that is what tells EF to make the relationship, not having it gives you the null reference exception

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.