-1

I have a following query throwing error as mentioned in subject

public async Task<IEnumerable<MyModel>> GetDataAsync()
{
    return await _context.baseTable.SelectData().AsNoTracking().ToListAsync();
}
    
public static IQueryable<MyModel> SelectData(this IQueryable<relet> baseTable)
{
    return baseTable
        .Where(h => h.table1 != null && h.table1.table2 != null)
        .Select(lev => new {
            table3Collection = lev.table1.table2.table3, //table3 is ICollection
            Table5Key = lev.table5 != null ? lev.table5.id : null,
            Table4Key = lev.table1.table2.table4 != null ?  lev.table1.table2.table4.id : null,
        }).ToList()
        .SelectMany(x => {
            return x.table3Collection.Select(h => new MyModel() {
                ContactKey = new Key
                {
                    Id = h.Id,
                    Type = h.Type
                },
                Table5Key = x.Table5Key,
                Table4Key = x.Table4Key
    
            });
        })
        .AsQueryable();
}

Can someone Give me idea how to use same LINQ query in group join way? Problem is occuring at .ToListAsync() line

phuzi
  • 12,078
  • 3
  • 26
  • 50
Kamran Shahid
  • 3,954
  • 5
  • 48
  • 93
  • 1
    You don't have `ToListAsync()` anywhere in the code you have shown us! – phuzi Jul 14 '22 at 08:52
  • It is called in the calling method – Kamran Shahid Jul 14 '22 at 09:20
  • You should show us ___all___ the relevant code. The easy answer is don't return IQueryable and don't call `AsQueryable()` then! – phuzi Jul 14 '22 at 09:26
  • That thing is already achieved. Any way I can Convert my List to AsyncList . basically i wanted to await the result – Kamran Shahid Jul 14 '22 at 09:30
  • Show us some more code (edit the question) that includes where the error is actually thrown and explain in detail what you're trying to acheive (again edit the question to add this detail). – phuzi Jul 14 '22 at 09:32
  • May be related: https://stackoverflow.com/questions/48743165/toarrayasync-throws-the-source-iqueryable-doesnt-implement-iasyncenumerable – phuzi Jul 14 '22 at 10:10
  • What happens if you remove `.AsQueryable()` – phuzi Jul 14 '22 at 10:10
  • I think Queryable support async. if i remove it i will lost it – Kamran Shahid Jul 14 '22 at 10:52
  • What type does `SelectMany` return? Does that type also implement `IQueryable`? – phuzi Jul 14 '22 at 10:55
  • SelectMany always return IEnumerable and here it is returning MyModel enumrable which i am converting to Asqueryable – Kamran Shahid Jul 14 '22 at 11:11
  • Only Problem I agains saying is with ToListAsync() – Kamran Shahid Jul 14 '22 at 11:11
  • Why did you use `ToList()` in `SelectData()`? At this point you loaded everything in memory *synchronously*. The rest of the code is an in-memory query so `ToListAsync()` would make no sense even if it was possible. Using `AsQueryable()` won't change the fact you already loaded the results in memory – Panagiotis Kanavos Jul 14 '22 at 11:56
  • What are you trying to do with that query? EF Core (and all ORMs) deal with *Entities and classes*, not tables. You aren't writing an embedded SQL query, you're writing an ORM query that will be mapped to SQL. Complicated queries like this are almost always a smell and an attempt to rewrite SQL as LINQ – Panagiotis Kanavos Jul 14 '22 at 11:57
  • If you want to execute anything asynchronously, split this long chain of calls at `ToList()` and replace it with `ToListAsync()`. After that, process the results with the rest of the code, as IEnumerables – Panagiotis Kanavos Jul 14 '22 at 11:58

1 Answers1

2

You cannot create IQueryable from IEnumerable and use asynchronous extensions. Actually you just need to correct your query and remove unnecessary materializations.

public static IQueryable<MyModel> SelectData(this IQueryable<relet> baseTable)
{
    return 
        from lev in baseTable
        from t3 in lev.table1.table2.table3
        select new MyModel
        {
            ContactKey = new Key
            {
                Id = lev.Id,
                Type = lev.Type
            },
            Table5Key = (int?)lev.table5.Id,
            Table4Key = (int?)lev.table1.table2.table4.Id
        };
}

Note that from simplified query we can see that t3 is not used. It means that we just duplicate records.

Svyatoslav Danyliv
  • 21,911
  • 3
  • 16
  • 32