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 Extensions • Entity Framework Classic • Bulk Operations • Dapper Plus
Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval Function • SQL 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.