简体   繁体   中英

EF filtering child collection and grandchild collection

I am using Entity Framework (ver 6) with ODP.net (for oracle)

I have a one to many relationship from Courses to Lectures to Lecturetags.

I have a search form where users can search by coursename, lecturename or lecturetags and so forth..

I am having a hard time to filter out and show only courses/lectures that pass the search criteria and show only those.

Here is what i have tried initially

 IQueryable<COURSES> result = db.Courses.AsQueryable();
 public IQueryable<COURSES> GetCourseDetails(SearchModel searchModel) 
 {
    if (!string.IsNullOrEmpty(searchModel.CourseName))
      result = result.Where(x => COURSE_NAME.Contains(searchModel.CourseName));
    if (!string.IsNullOrEmpty(searchModel.LectureName))
       result = result.Where(x => x.LECTURES.Any(y => y.LEC_NAME.Contains(searchModel.LectureName)));
 }

Obviously this isnt working since its actually not filtering parent=>Child.(this loads all the lecture child objects)

So I tried this..Converted the return type to an IEnumerable and see whether i can fetch only related entities...but this didnt work either and i am getting the same search result.

 if (!string.IsNullOrEmpty(searchModel.LectureName))
      {
          var searchResult = from course in db.COURSES
                             select new
                                {
                                  course,
                                  lectures = from lecture in course.LECTURES
                                  where  lecture.LEC_NAME.Contains(searchModel.LectureName)
                                  select lecture
                                };
          result = searchResult.AsEnumerable().Select(c => c.course);
        }

I am new to EF, so i am not sure whats the best way to do this ? I have several related tables and i am trying to see what would be the best way to filter out.

One other option would be to fetch all courses which has the lecture name and filter them out again at the presentation layer.

UPDATE

I was able to get the second method work by adding this line

  db.Configuration.LazyLoadingEnabled = false;

However i am looking for ways to use the IEnumerable result generated from above to be used for further filtering such as LectureTags (bring those lectures that has a specified lecture name as well as specified lecture tag)

It looks like you are mostly on the right track. Please try the following EF code and let me know if that works. I know that you can include string.IsNullOrEmpty in EF queries when using MSSQL as your data provider, but I'm not sure if that works with Oracle.

public IEnumerable<COURSES> GetCourseDetails(SearchModel searchModel) 
{
    // Not sure what your database context is named, but use the correct name here
    using (var db = new DatabaseContext())
    {
        var coursesToReturn = db.Courses.Where(c =>
             (string.IsNullOrEmpty(searchModel.CourseName) || c.COURSE_NAME.Contains(searchModel.CourseName)) &&
             (string.IsNullOrEmpty(searchModel.LectureName) || c.LECTURES.Any(l => l.LEC_NAME.Contains(searchModel.LectureName)) &&
             (string.IsNullOrEmpty(searchModel.LectureTag) || c.LECTURES.Any(l => l.LECTURE_TAGS.Any(lt => lt.TAG_NAME.Equals(searchModel.LectureTag))));

        return coursesToReturn.AsEnumerable();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM