-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The data types varchar and nvarchar are incompatible in the '^' operator #35093
Comments
Confirmed regression from 8.0 to 9.0; the new boolean XOR logic likely needs to be applied only when the store type is bit (whereas here we have a value converter). For the following query with a value-converted enum, we now generate incorrect SQL with XOR logic (with a regular non-converted string the SQL is OK): _ = await context.Orders
.Select(order => new { Paid = order.State == OrderState.Paid })
// The following is OK (non-value-converted string)
// .Select(order => new { IsNameFoo = order.Name == "Foo" })
.ToListAsync(); 9.0 SQL: SELECT ~CAST([o].[State] ^ N'Paid' AS bit) AS [Paid]
FROM [Orders] AS [o] 8.0 SQL: SELECT CASE
WHEN [o].[State] = N'Paid' THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [Paid]
FROM [Orders] AS [o] Full reproawait using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
_ = await context.Orders
.Select(order => new { Paid = order.State == OrderState.Paid })
// The following is OK (non-value-converted string)
// .Select(order => new { IsNameFoo = order.Name == "Foo" })
.ToListAsync();
public class BlogContext : DbContext
{
public DbSet<Order> Orders { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().Property(o => o.State).HasConversion<OrderStateConverter>();
}
private class OrderStateConverter() : ValueConverter<OrderState, string>(
os => os.ToString(),
s => Enum.Parse<OrderState>(s));
}
public class Order
{
public int Id { get; set; }
public OrderState State { get; set; }
public string Name { get; set; }
}
public enum OrderState { Unpaid, Paid } /cc @ranma42 - let me know if this is something you want to take a look at (and have time), as you worked on the original change. |
I will try and tackle this next weekend (aka it's unlikely I will have a PR ready before next week). (the same issue is likely also affecting the |
@roji @ranma42 integer data types are fine as well https://learn.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-exclusive-or-transact-sql?view=sql-server-ver16 |
@ChrisJollyAU they are fine in that they support the operators (^ and ~), but they might not match the expected Boolean semantics. |
Projection to Boolean of Equals comparator of a Enum property (that has custom ValueConverter to string) with one of possibles values of Enum translates to SQL with the new XOR ('^') operator implementation, causing 'The data types varchar and nvarchar are incompatible in the '^' operator'.
Translate to SQL as
EF Core version: 9.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 11 10.0.22631
IDE: Visual Studio 2022 17.11.6
The text was updated successfully, but these errors were encountered: