0

I have such a case study:

ToList() case:

    List<CategoryType> categories = (from c in categoryTypes where c.IsSysParam == isSysParamCategory select new CategoryType { Code = c.Code, CreateDate = c.CreateDate, EditDate = c.EditDate, IsProductCategory = c.IsProductCategory, IsSysParam = c.IsSysParam, Name = c.Name, TypeId = c.TypeId, ValueTypes = new List<ValueType>() }).ToList();

    List<ValueType> valueTypeList = new List<ValueType>();
    foreach (var c in categories.ToList())
    {
        valueTypeList = categoryTypes.Where(x => x.TypeId == c.TypeId).SelectMany(v => v.ValueTypes).Where(v => v.ParentValueId == null).ToList();
        c.ValueTypes = valueTypeList;
    }

enter image description here

IQueryable case:

When I change in first query - List<CategoryType> to IQueryable<CategoryType> and remove ToList() from the end of query then I dont have any result:

enter image description here

Question:

I am asking for an explanation, I do not understand why this is happening. I know that the IQueryable makes some part of the work on the database side.

Edit: The code is working, pictures shows the final effect.

I have:

  public IQueryable<CategoryType> CategoryTypePagination { get; set; }

and in the end of ToList() case:

this.CategoryTypePagination = categories.AsQueryable();

in IQueryable case just removed .AsQueryable()

szkut
  • 353
  • 2
  • 22
  • 1
    Post the *actual* code, not screenshots and descriptions. The code and screenshots don't match. The object definitions are missing. You claim you were able to assign an IQueryable to a *List* variable without compilation errors? – Panagiotis Kanavos Sep 06 '18 at 08:44
  • I think [this link](https://blogs.msdn.microsoft.com/charlie/2007/12/10/linq-and-deferred-execution/) is much more helpfull than my explanation attempts – Mong Zhu Sep 06 '18 at 08:46
  • Panagiotis Kanavos - I edited post. – szkut Sep 06 '18 at 09:00

2 Answers2

1

You have to look at "Deferred Query Execution" and "Immediate Query Execution"

Bianca
  • 382
  • 4
  • 12
  • The code sets the `ValueTypes` property directly - even though in the second "snippets" the value is supposed to be an IQueyrable that just can't be assigned to a List – Panagiotis Kanavos Sep 06 '18 at 08:45
0

Accrodingly to this, IQueryable uses something called lazy loading.

So the results of IQueryable aren't loaded until they are first used, for example in Sum, ToList or ToArray methods, while ToList requieres data to be loaded. Thus you see the difference after initailizing both objects.

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • It's more likely that the code doesn't even run. It's trying to assign an IQueryable to a List variable. This should throw – Panagiotis Kanavos Sep 06 '18 at 08:46
  • @PanagiotisKanavos No, OP stated that he changed the type to `IQueryable` and removed `ToList()` method. As can be also seen in [pictures, code runs well. – Michał Turczyn Sep 06 '18 at 08:48
  • 1
    The screenshots don't match the code. They are from a *different* snippet entirely. The OP doesn't explain what changes were made - IQueryable doesn't have a `.Count` property. If `ValueTypes` is still a list, how was an *IQueryable* assigned to it? And since `ValueTypes` contains the query's *root* results its count wouldn't be affected by lazy loading – Panagiotis Kanavos Sep 06 '18 at 08:55