.NET 6 WebAPI - System.ArgumentException: At least one object must implement IComparable

0

Witam.
Halp człowieki!
Przygotowuje się do większego projektu, które będzie PWA. Mam testowe API, które ma za zadanie tylko dawać jakieś dane, bo głównie chodzi o front. Korzystam z OData.

CONTROLLER

        [HttpGet]
        [EnableQuery]
        public async Task<IActionResult> Get()
        {
            try
            {
                using (IDbConnection db = new SqlConnection(_configuration.GetConnectionString("CompanyDatabase")))
                {
                    var products = await db.QueryAsync<Product>(ProductsQuery);

                    if(products.Count() > 0)
                    {
                        return Ok(products);
                    }

                    return NotFound();
                }
            }
            catch( Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

private readonly string ProductsQuery = @"select Twr_TwrId [Id], DAB_Wartosc [Image], Twr_JM [Unit], Twr_GIDNumer [GroupId],  Twr_Kod [Code], Twr_Nazwa [Name], Twr_EAN [Ean], TwI_Wartosc [Quantity], TwC_Wartosc [Price]
from CDN.Towary A
join CDN.TwrIlosci on TwI_TwIId =
(SELECT TOP 1 IL.TwI_TwIId From CDN.TwrIlosci IL Where IL.TwI_TwrId = A.Twr_TwrID And IL.TwI_MagId = 1 And convert(date, IL.TwI_Data, 120) <= Convert(DATE, getdate(),120) ORDER BY IL.TwI_Data DESC)
JOIN CDN.TwrCeny ON TwC_TwrID = A.Twr_TwrId and TwC_TwCNumer = Twr_TwCNumer
left join CDN.DaneBinarneLinki on A.Twr_TwrId = DBL_TwrID
left join CDN.DaneBinarne on DBL_DabId = DAB_DABID
where Twr_Typ = 1"

Dostaje błąd jak w tytule. Niczego nie sortuje. Odpytuje tylko pierwsze 50 https://localhost:44469/api/products?&top=50. Co najdziwniejsze to debugując dostaje dane, nie rzuca wyjątkiem (catch). To jakiś bug w OData?

STACKTRACE

"System.ArgumentException: At least one object must implement IComparable.
   at System.Collections.Comparer.Compare(Object a, Object b)
   at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
   at System.Linq.EnumerableSorter`2.CompareAnyKeys(Int32 index1, Int32 index2)
   at System.Linq.EnumerableSorter`2.CompareAnyKeys(Int32 index1, Int32 index2)
   at System.Linq.EnumerableSorter`2.CompareAnyKeys(Int32 index1, Int32 index2)
   at System.Linq.EnumerableSorter`2.CompareAnyKeys(Int32 index1, Int32 index2)
   at System.Linq.EnumerableSorter`2.CompareAnyKeys(Int32 index1, Int32 index2)
   at System.Linq.EnumerableSorter`2.PartialQuickSort(Int32[] map, Int32 left, Int32 right, Int32 minIdx, Int32 maxIdx)
   at System.Linq.OrderedEnumerable`1.GetEnumerator(Int32 minIdx, Int32 maxIdx)+MoveNext()
   at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter`2.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteCore[TValue](JsonConverter jsonConverter, Utf8JsonWriter writer, TValue& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
"
0

return Ok(products.ToList())

0

Nope. Dzieje się to samo. Problem jest zdecydowanie w OData, ponieważ na czas znalezienia rozwiązania usunąłem z endpointa [EnableQuery] i nie ma problemu. Pytanie tylko czy ja mam coś źle? Czy to OData ma buga, a może OData jeszcze nie ogarnia za dobrze .NET 6?

0

Jak order by usuniesz z query to jest tak samo?

0

Ten order by jest w joinie i on tam raczej musi być. Usunąłem, zaczęło działać, przywróciłem tak jak było podczas "nie działania" i teraz działa z nim, nie ma błędu... WTF? 🤦‍♂️🤷‍♀️

#EDIT
Sprostowanie - to nie order by. W momencie kiedy nie korzystam z [EnableQuery] dopisuje do zapytania SQL top(150) żeby mi nie wyciągał prawie 2k towarów z obrazkami w base64. Po twojej sugestii usunąłem order by ale zapomniałem usunąć też top(150). Nie potrzebuje tego top jeśli korzystam z OData i przez to nie działa.

0

Mam to!
Nie dawało mi to spokoju i włączył mi się Szerlok. Skoro działa z top(150) to postanowiłem lecieć co 100 i sprawdzać kiedy się wykrzaczy. Doleciałem do top(800) i okazało się, że któryś join duplikuje mi dane, jest dwa razy ten sam towar w wyniku zapytania na pozycji 799 i 800. Gdy zrobię top(799) to działa, ale z top(800) już nie. Dziwi mnie trochę, że OData sobie z tym nie radzi, a może to coś innego. Google niewiele pokazuje jak się wyszuka coś o powtórzeniach, bo ogólnie OData nie powinien mieć z tym problemu. Używam najnowszej wersji 8.04.

0

ciekawe czy problem by wystepowal, gdybys w encji nadpisal metode equals (i np porownal po id) ;) moze wtedy odata by sobie poradzil =p

1 użytkowników online, w tym zalogowanych: 0, gości: 1