List vs IEnumerable vs IQueryable when defining Navigation property

前端 未结 4 1872
难免孤独
难免孤独 2020-12-15 21:35

I want to create a new model object named Movie_Type in my ASP.NET MVC web application. What will be the differences if I define the navigation proprty of this

4条回答
  •  星月不相逢
    2020-12-15 22:22

    You cannot use a navigation property of type IQueryable. You must use ICollection or some collection type which implements ICollection - like List. (IQueryable does not implement ICollection.)

    The navigation property is simply an object or a collection of objects in memory or it is null or the collection is empty.

    It is never loaded from the database when you load the parent object which contains the navigation property from the database.

    You either have to explicitely say that you want to load the navigation property together with the parent which is eager loading:

    var movieTypes = context.Movie_Types.Include(m => m.Movies).ToList();
    // no option to filter or sort the movies collection here.
    // It will always load the full collection into memory
    

    Or it will be loaded by lazy loading (which is enabled by default if your navigation property is virtual):

    var movieTypes = context.Movie_Types.ToList();
    foreach (var mt in movieTypes)
    {
        // one new database query as soon as you access properties of mt.Movies
        foreach (var m in mt.Movies)
        {
            Console.WriteLine(m.Title);
        }
    }
    

    The last option is explicit loading which comes closest to your intention I guess:

    var movieTypes = context.Movie_Types.ToList();
    foreach (var mt in movieTypes)
    {
        IQueryable mq = context.Entry(mt).Collection(m => m.Movies).Query();
        // You can use this IQueryable now to apply more filters
        // to the collection or sorting, for example:
        mq.Where(m => m.Title.StartWith("A"))   // filter by title
          .OrderBy(m => m.PublishDate)          // sort by date
          .Take(10)                             // take only the first ten of result
          .Load();                              // populate now the nav. property
        // again this was a database query
    
        foreach (var m in mt.Movies)    // contains only the filtered movies now
        {
            Console.WriteLine(m.Title);
        }
    }
    

提交回复
热议问题