Alexandr Sulimov
Alexandr Sulimov

Reputation: 1924

Entity framework not all property load

In my code Entity Framework load only one navigation property

//Model
public class MemorialData
{
    public MemorialData()
    {
        Id = Guid.NewGuid();
    }

    [Key]
    public Guid Id { get; set; }

    public virtual Memorial Memorial { get; set; }
    public Guid MemorialId { get; set; }

    public virtual UserData Author { get; set; }
    public Guid AuthorId { get; set; }

    public string Data { get; set; }
}

public ActionResult AddData(MemorialData model)
{
    MemorialData md = db.MemorialDatas.Find(model.Id);
    if (md == null)
    {
        System.Diagnostics.Debug.WriteLine("md == null Creating");
        md = new MemorialData();
        md.MemorialId = model.MemorialId;
        //md.Memorial = db.Memorials.Find(model.MemorialId);
        md.Data = model.Data;
        md.AuthorId = db.CurrentUser.Id;
        db.MemorialDatas.Add(md);
    }
    else
    {
        md.Data = model.Data;
    }
    System.Diagnostics.Debug.WriteLine("Saving " + md.Id);
    db.SaveChanges();

    System.Diagnostics.Debug.WriteLine("Load " + md.Id);
    md = db.MemorialDatas.Find(md.Id);
    System.Diagnostics.Debug.WriteLine("AuthorId " + md.AuthorId);
    System.Diagnostics.Debug.WriteLine("Author is NULL? " + (md.Author == null));
    System.Diagnostics.Debug.WriteLine("MemorialId " + md.MemorialId);
    System.Diagnostics.Debug.WriteLine("Memorial is NULL? " + (md.Memorial == null));
}

Debug output

md == null Creating

Saving 1b21f49f-749d-4cd3-8c3f-1f128ce67f6f

Load 1b21f49f-749d-4cd3-8c3f-1f128ce67f6f

AuthorId 7b1fc9c4-4930-45be-9196-44b3f49e6770

Author is NULL? False

MemorialId a813a8f4-409b-4c97-8d2d-cb19aff267bb

Memorial is NULL? True ???

Why Memorial is null but Author not null?

Where to find the cause of the error?

P.S.

If uncomment //md.Memorial = db.Memorials.Find(model.MemorialId);

Memorial is NULL? False ???

Upvotes: 1

Views: 312

Answers (1)

Slauma
Slauma

Reputation: 177163

I assume that db.CurrentUser is a User entity. Apparently in your AddData method this entity is already loaded because you are using:

md.AuthorId = db.CurrentUser.Id;

(If not, you would get a NullReferenceException.)

When you set the AuthorId EF will set the Author navigation property as well when DetectChanges is called (happens inside of db.MemorialDatas.Add) because the Author (=db.CurrentUser) is in memory and probably attached to the context.

The Memorial entity is not loaded, you seem to have only the model.MemorialId available.

Your test to write and read the MemorialData happens in the same context and ...

md = db.MemorialDatas.Find(md.Id);

...doesn't run a database query because you have added it to the context before, hence Find can return it from memory with md.Author being set.

md.Memorial is not set and when you access it EF won't run a lazy loading query because you didn't create a dynamic proxy but just a plain Entity with md = new MemorialData().

In order to fix the problem and to enable lazy loading so that md.Memorial can be loaded from the database you must create a dynamic proxy (instead of md = new MemorialData();):

md = db.MemorialDatas.Create();

Upvotes: 3

Related Questions