Entity Framework 6 context not retrieving navigation properties

南楼画角 提交于 2019-12-05 10:09:31

I change the query code Ihad in Linq with this one.

    internal Client GetClient(string userId, bool lazyLoadingEnabled = true)
    {
        using (var context = new ApplicationDbContext())
        {
            context.Configuration.LazyLoadingEnabled = lazyLoadingEnabled;

            var client = context
                        .Client
                        .Include(s => s.ScholarLevelDetails)
                        .Include(s => s.JobsExperiences)
                        .Include(s => s.CapacitationCourses)
                        .Include(s => s.Relatives)
                        .FirstOrDefault(s => s.ApplicationUserId == userId);

            return client;
        }
    }

And now it works. however I still have some questions I´d lve to discuss with you readers and colleagues.

Why plain Linq doesn´t work? Why it doesn matter if lazyloading is enabled or not, this code works the same everytime?

The problem is that your context fell out of scope before the navigational properties could be loaded.

To do what you want, you would need to change how you are working with your context, or just eager load the entities you are going to need via table join(s) using the query syntax that you are using, or via .Include() lambda expressions if you use the lambda query syntax.

    using (var context = new ApplicationDbContext())
    {
        context.Configuration.LazyLoadingEnabled=lazyLoadingEnabled;

        var client = (from _client in context.Client
                      where _client.ApplicationUserId == userId
                      select _client).FirstOrDefault();

        return client; //at this point, your context is gone, and no 
        //navigational properties will be loaded onto your client object, 
        //even if you try to navigate them. You may even get exceptions if
        //attempting to navigate to some properties.
    }

Here is a join example:

var client = (from _client in context.Client
              join t in context.Table on _client.Val equals t.val //this will eager load Table property on client.
              where _client.ApplicationUserId == userId
              select _client).FirstOrDefault();

You should use Include method for properties.

_context.Client.Include(c=>c.JobsExperiences) ... and all props like this

but for you is better not to use lazy loading. Cause context become inactive after you return from method.

Using EF 6, I had to use (lamba's and Client keyword is unavailable):

    using (var context = new SyntheticData.EF.DBContext())
    {
        var item = (from t in context.TEMPLATEs
                        .Include("DATASET")
                        .Include("COLUMNs")
                        .Include("SORTs")
                        .Include("FILTERs")
                    where t.USERID == identityname && t.ID == id select t).FirstOrDefault();
        return item;
    }

This filled in relationship classes with syntax like:

  • item.DATASET.xxx
  • item.COLUMNs[0].xxx

The "using (var context" construct is good practice because it insures your connection to the database will be released back to the pool. If you don't, you can end up running out of conenctions for busy systems.

Just in case this helps someone I was not getting any navigation properties and my problem seemed to be that EF did not properly hookup the properties because I was using an interface as the navigational property type and I needed to use actual type. Unless anyone knows how to use annotations or something to tell EF the actual type that the property is mapped to.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!