zzzprojects/EntityFramework.DynamicFilters

Enum-of-byte is unnecessarily cast to int

TobiasMarklund opened this issue · 6 comments

Description

When adding a filter to a byte-backed enum field which is stored as a (in Sql Server) 'tinyint' column an unnecessary CAST ( x AS int ) is generated, causing unnecessary strain on the database.

E.g. a field of the following type:
public enum CustomerStatus : byte {
Normal = 0,
Inactive = 1,
Deleted = 2
}

With the following filter:
modelBuilder.Filter("IsNotDeleted", (Customer d, CustomerStatus status) => d.Status != status, CustomerStatus.Deleted);

Will generate the following SQL:
SELECT
[Extent1].[CustomerID] AS [CustomerID],
[Extent1].[Name] AS [Name],
[Extent1].[Status] AS [Status]
FROM [dbo].[Customers] AS [Extent1]
WHERE ( CAST( [Extent1].[Status] AS int) <> CAST( @DynamicFilterParam_000001 AS int))

The expected result should be:
SELECT
[Extent1].[CustomerID] AS [CustomerID],
[Extent1].[Name] AS [Name],
[Extent1].[Status] AS [Status]
FROM [dbo].[Customers] AS [Extent1]
WHERE ( [Extent1].[Status] <> @DynamicFilterParam_000001 )

Fiddle or Project

https://dotnetfiddle.net/3iJBCx

Further technical details

  • EF version: 6.3
  • EF DynamicFilters version: 3.1.0
  • Database Provider: SqlServer

Hello @TobiasMarklund ,

Thank you for reporting.

We tried the same Fiddle without our library and as expected, there is no CAST.

We will look at why this cast happen in the library

Best Regards,

Jonathan


Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework ExtensionsEntity Framework ClassicBulk OperationsDapper Plus

Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval FunctionSQL Eval Function

Hello @TobiasMarklund ,

We looked at it this weekend, however, we didn't succeed to find a solution.

We tried to move some code but unfortunately, the cast was always required at the end when comparing both DbExpression.

So unless you have found something on your side that might worth to investigate, I believe we will close this issue since we have not found an alternative way to make it works without the cast.

Seems like it is the C# compiler which adds that cast for unknown reasons.
I have been experimenting with modifying Binary equality expressions in the LambdaToDbExpressionVisitor where I check if one operand is a converted byte enum and if the other operand is also possible to convert to byte to make a new BinaryExpression with byte operands.

I can make a pull request with my attempt.

Why did you close this?

Oops! Sorry,

The issue was marked as to be "closed" but the status was not updated with your last answer. So we closed it by mistake ;(

Now opened ;)

Hello @TobiasMarklund ,

Thank you for your contribution.

The v3.1.1 has been released. It includes your both pull requests.