3

I have the following Linq statement, which works totally fine:

query = query.OrderBy(m => m.MATERIAL_TXT.Where(mt => mt.LANG == "EN").FirstOrDefault().LTEXT);

Now I'm trying to make it dynamic by using the string based syntax from Linq.Dynamic:

query = query.OrderBy("MATERIAL_TXT.Where(LANG==\"EN\").FirstOrDefault().LTEXT");

But it throws the exception :

"No applicable aggregate method 'FirstOrDefault' exists"

It has to bedynamic so that it accepts other names instead of "MATERIAL_TXT".

What am I missing?

dagon
  • 65
  • 6

2 Answers2

1

According to the documentation:

A subset of the Standard Query Operators is supported for objects that implement IEnumerable. Specifically, the following constructs are permitted, where seq is an IEnumerable instance, predicate is a boolean expression, and selector is an expression of any type:

  • seq.Where(predicate)
  • seq.Any()
  • seq.Any(predicate)
  • seq.All(predicate)
  • seq.Count()
  • seq.Count(predicate)
  • seq.Min(selector)
  • seq.Max(selector)
  • seq.Sum(selector)
  • seq.Average(selector)

FirstOrDefault isn't on the list, so it's reasonably safe to assume it isn't supported.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • Do you have any idea how i could achieve that functionality without using FirstOrDefault()? – dagon Sep 20 '19 at 15:18
  • @dagon It's not easy; this kind of operation is very hard to do in SQL (just look at what the original query you had looks like in SQL). In the end, that's why `FirstOrDefault` isn't supported - Any, Min, Count, Sum... all of those are aggregate functions supported by pretty much all databases and especially MS SQL, which is the main target. MS SQL *doesn't* have "first". You basically need to rewrite the whole query, rather than just supplying a custom order by expression. You'll probably need to do that manually - take inspiration from how EF does it in the original case. – Luaan Sep 20 '19 at 19:15
  • Ok, too bad. I'll accept your anwser, since what i want to do seems to be impossible. – dagon Sep 22 '19 at 14:40
1

You can't use FirstOrDefault as string like that.

if you want to create dynamic orderBy try this :

Func<IQueryable<YourEntityType>, IOrderedQueryable<YourEntityType>> orderBy;

   orderBy = x => x.OrderBy(m => m.MATERIAL_TXT.Where(mt => mt.LANG == "EN").FirstOrDefault().LTEXT);

Then you can use it like this :

orderBy(query);

for example you can use it in another method :

public List<YourEntityType> YourMethodName(Func<IQueryable<YourEntityType>, IOrderedQueryable<YourEntityType>> orderBy,IQueryable<YourEntityType> query=null)
{
     query=query ?? GetYourEntityTypeList().AsQueryable();
     return orderBy(query).ToList();
}

I Hope it will be useful .

masoud
  • 355
  • 2
  • 10
  • "MATERIAL_TXT" needs to be dynamic, so that won't work. – dagon Sep 22 '19 at 14:37
  • 1
    @dagon This doesn't give you a completely dynamic approach, but you can write ten different versions in advance, and select between those at runtime. If the possible orderings you have to do is predictable, this is a great approach. – Luaan Sep 22 '19 at 15:31
  • In the end i ended up making an expression for each case individually, because i now all possibilities. Thanks for that. – dagon Oct 02 '19 at 09:14