Open
Description
Bug description
When IsConcurrencyToken is used with property in Owned entity which is mapped to json column => incorrect sql is generated. For the provided code I see the following in logs:
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (6ms) [Parameters=[@p0='?' (Size = 63), @p1='?' (DbType = Guid)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
UPDATE [Entities] SET [Owned] = @p0
OUTPUT 1
WHERE [Id] = @p1;
I expect to see smth like ...WHERE [id] = @p1 AND JSON_VALUE('$.Version') = @p2
where @p2
is old concurrency token value
Your code
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var services = new ServiceCollection()
.AddLogging(e => e.AddConsole())
.AddDbContext<AppDbContext>()
.BuildServiceProvider();
void Initialize()
{
using var scope1 = services.CreateScope();
var dbContext = scope1.ServiceProvider.GetRequiredService<AppDbContext>();
dbContext.Database.EnsureDeleted();
dbContext.Database.EnsureCreated();
dbContext.Entities.Add(new Entity
{
Owned = new OwnedEntity()
{
Text = "123",
Version = Guid.NewGuid(),
}
});
dbContext.SaveChanges();
}
Initialize();
var dbContext = services.CreateScope().ServiceProvider.GetRequiredService<AppDbContext>();
var entity = dbContext.Entities.First();
entity.Owned = new OwnedEntity()
{
Text = "444",
Version = Guid.NewGuid(),
};
dbContext.Entities.Update(entity);
dbContext.SaveChanges();
public class AppDbContext : DbContext
{
private readonly ILoggerFactory _loggerFactory;
public AppDbContext(ILoggerFactory loggerFactory, DbContextOptions<AppDbContext> options) : base(options)
{
_loggerFactory = loggerFactory;
}
public DbSet<Entity> Entities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer("")
.UseLoggerFactory(_loggerFactory);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Entity>(n =>
{
n.ToTable("Entities").HasKey(e => e.Id);
n.OwnsOne(e => e.Owned, n1 =>
{
n1.ToJson("Owned");
n1.Property(e => e.Text).HasMaxLength(250).IsRequired();
n1.Property(e => e.Version).IsConcurrencyToken().IsRequired();
});
});
}
}
public class Entity
{
public Guid Id { get; set; }
public OwnedEntity Owned { get; set; }
}
public class OwnedEntity
{
public string Text { get; set; }
public Guid Version { get; set; }
}
Stack traces
Verbose output
EF Core version
9.0.4
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.NET 9
Operating system
Windows 11
IDE
No response