0

I'm trying to sort the data by the type "V0003", "4323Fw" but an error occurs with comparer, what is going wrong and how can I sort in IQueryable?

My comparer:

    public class NumericStringComparer : IComparer<string>
    {
        public int Compare(string s1, string s2)
        {
            const int S1GreaterThanS2 = 1;
            const int S2GreaterThanS1 = -1;
            const int S2EqualsS1 = 0;

            var isS1Numeric = IsNumeric(s1);
            var isS2Numeric = IsNumeric(s2);

            if (isS1Numeric && isS2Numeric)
            {
                var firstNum = Convert.ToInt64(s1);
                var secondNum = Convert.ToInt64(s2);

                if (firstNum > secondNum)
                {
                    return S1GreaterThanS2;
                }

                if (firstNum < secondNum)
                {
                    return S2GreaterThanS1;
                }

                return S2EqualsS1;
            }

            if (isS1Numeric)
            {
                return S2GreaterThanS1;
            }

            if (isS2Numeric)
            {
                return S1GreaterThanS2;
            }

            return string.Compare(s1, s2, true, CultureInfo.InvariantCulture);

            static bool IsNumeric(string value)
            {
                return long.TryParse(value, out _);
            }
        }
    }

My sort:

query.OrderBy(bdc => bdc.Code, comparer), // query is IQueryable<MyClass>

Error:

"The LINQ expression""DbSet()\r\n .Where(bdc => bdc.DateEnd >= DateTime.UtcNow && bdc.Deleted == False)\r\n .OrderByDescending(bdc => bdc.Id)\r\n .Include(bdc => bdc.InverseParent)\r\n .ThenInclude(bdc => bdc.InverseParent)\r\n .ThenInclude(bdc => bdc.InverseParent)\r\n .Where(bdc => (int)bdc.StagesBudgetCycle == (int)(short)__StagesBudgetCycle_0 || bdc.InverseParent\r\n .AsQueryable()\r\n .Any(children => (int)children.StagesBudgetCycle == (int)(short)__StagesBudgetCycle_0 || children.InverseParent\r\n .AsQueryable()\r\n .Any(children => (int)children.StagesBudgetCycle == (int)(short)__StagesBudgetCycle_0 || children.InverseParent\r\n .AsQueryable()\r\n .Any(children => (int)children.StagesBudgetCycle == (int)(short)__StagesBudgetCycle_0))))\r\n .OrderBy(\r\n keySelector: bdc => bdc.Code, \r\n comparer: __p_1)""could not be translated. Either rewrite the query in a form that can be translated", "or switch to client evaluation explicitly by inserting a call to""AsEnumerable", "AsAsyncEnumerable", "ToList", "or""ToListAsync"". See https"://go.microsoft.com/fwlink/?linkid=2101038 for more information.

DevLife
  • 519
  • 1
  • 4
  • 6
  • 2
    This is C#, not SQL. EF needs to be able to translate your code into SQL, and with this code, it can't. – CodeCaster Nov 09 '21 at 10:35
  • Yeah. Gratulations - you just found a limit of EF LINQ Providers: they are not a true AI that can analyze your C# Code. You will have to work around that. – TomTom Nov 09 '21 at 10:38
  • 1
    If your columns/fields represents numbers, why are you storing them as strings? – JonasH Nov 09 '21 at 10:39
  • @JonasH Codes of the next type - "123a", "A2342" – DevLife Nov 09 '21 at 11:00
  • As the message says, you'll need to convert the query result to an enumerable or list before you do the OrderBy – John M Nov 09 '21 at 11:21
  • Do it on the client: `query.AsEnumerable().OrderBy(bdc => bdc.Code, comparer)` – Magnus Nov 09 '21 at 12:54
  • Unfortunately, pagination and filtering are used there, if you use it on c #, you will have to unload the entire table – DevLife Nov 10 '21 at 05:24

0 Answers0