EF Lambda: The Include path expression must refer to a navigation property [duplicate]

[亡魂溺海] 提交于 2019-12-28 03:11:48

问题


Here is my expression:

Course course = db.Courses
  .Include(
    i => i.Modules.Where(m => m.IsDeleted == false)
      .Select(s => s.Chapters.Where(c => c.IsDeleted == false))
  ).Include(i => i.Lab).Single(x => x.Id == id);

I know the cause is Where(m => m.IsDeleted == false) in the Modules portion, but why does it cause the error? More importantly, how do I fix it?

If I remove the where clause it works fine but I want to filter out deleted modules.


回答1:


.Include is used to eagerly load related entities from the db. I.e. in your case make sure the data for modules and labs is loaded with the course.

The lamba expression inside the .Include should be telling Entity Framework which related table to include.

In your case you are also trying to perform a condition inside of the include, which is why you are receiving an error.

It looks like your query is this:

Find the course matching a given id, with the related module and lab. As long as the matching module and chapter are not deleted.

If that is right, then this should work:

Course course = db.Courses.Include(c => c.Modules)
                          .Include(c => c.Lab)
                          .Single(c => c.Id == id && 
                                       !c.Module.IsDeleted &&
                                       !c.Chapter.IsDeleted);



回答2:


but why does it cause the error?

I can imagine that sometimes the EF team regrets the day they introduces this Include syntax. The lambda expressions suggest that any valid linq expression can be used to subtly manipulate the eager loading. But too bad, not so. As I explained here the lambdas only serve as a disguised string argument to the underlying "real" Include method.

how do I fix it?

Best would be to project to another class (say, a DTO)

db.Courses.Select(x => new CourseDto {
    Id = x.Id,
    Lab = x.Lab,
    Modules = x.Modules.Where(m => !m.IsDeleted).Select( m => new ModuleDto {
        Moudle = m,
        Chapters = x.Chapters.Where(c => c.IsDeleted)
    }
}).Single(x => x.Id == id);

but that may be a major modification for you.

Another option is to disable lazy loading and pre-load the non-deleted Modules and Chapters of the course in the context by the Load command. Relationship fixup will fill the right navigation properties. The Include for Lab will work normally.

By the way, there is a change request for this feature.



来源:https://stackoverflow.com/questions/15980665/ef-lambda-the-include-path-expression-must-refer-to-a-navigation-property

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