Skip to content

EF not generating SQL query correctly on fields that have conversion #31817

Closed as duplicate of#10434
@mhuete-iP

Description

@mhuete-iP

Setup

I have an entity model with a DateTime property named "Fecha Compra":

public class Ticket{
   // Some properties

   DateTime FechaCompra;

   // Some other properties
}

This DateTime value is stored in the SQLServer database as a BIGINT with the format "yyyyMMddHHmmss". Let's say I have the date 2023/09/20 09:15:00, then the BIGINT stored in the database is 20230920091500. This is achieved using the ".HasConversion" method in the property:

entity.Property(e => e.FechaCompra).HasConversion(new DateTimeToLongConverter());

Issue

My problem comes when I try to filter using this field. For example, I have the follwing chunk of code:

int count = repo.TicketsOperaciones
    .Where(c => ((c.FechaCompra.Date >= 2023-09-17 00:00:00) And (c.FechaCompra.Date <= 2023-09-20 00:00:00)))
    .Count();

When entity automatically converts this to the SQL query I get the following:

SELECT COUNT(*)
FROM [APP_TICKETS_OPERACIONES] AS [a]
WHERE (CASE
    WHEN CONVERT(date, [a].[FechaCompra]) >= CAST(20230917000000 AS bigint) THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END & CASE
    WHEN CONVERT(date, [a].[FechaCompra]) <= CAST(20230917000000 AS bigint) THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END) = CAST(1 AS bit)

As you can see, it is trying to compare a date on the left side of the comparison (it even has to convert it!!!) to a bigint in the right side of the comparison. So this gets me an exception every time:

Microsoft.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=No se permite la conversión explícita del tipo de datos bigint a date.
  Source=Core Microsoft SqlClient Data Provider
  StackTrace:
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at Microsoft.Data.SqlClient.SqlDataReader.get_MetaData()
   at Microsoft.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean isAsync, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String method)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.<>c.<MoveNext>b__21_0(DbContext _, Enumerator enumerator)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at SQLServerCity.TicketRepo.ObtenerListOperacionesImportes(GetRequestList opciones) in C:\iParksa\iParkCity_CSharp\Infrastructure\Salida\SQLServerCity\TicketRepo.cs:line 26
   at ServicesCity.TicketService.ObtenerListaImportesOperaciones(GetRequestList opciones) in C:\iParksa\iParkCity_CSharp\Services\ServicesCity\TicketService.cs:line 56

  This exception was originally thrown at this call stack:
    [External Code]
    SQLServerCity.TicketRepo.ObtenerListOperacionesImportes(Utilities.Classes.GetRequestList) in TicketRepo.cs
    ServicesCity.TicketService.ObtenerListaImportesOperaciones(Utilities.Classes.GetRequestList) in TicketService.cs

Provider and version information

EF Core version: 7.0.11
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 7.0
Operating system: Windows 11 22H2
IDE: Visual Studio 2022 17.7.4

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions