You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Byte array in owned entity mapped to JSON returns different value when using projection #3566
Hi, I encountered a problem while working with a byte array in an owned entity mapped to JSON - it looks like the materialization behaves differently when getting the whole entity vs getting only the specific property.
I would like to use this for encrypted columns, below is a simplified example.
using Microsoft.EntityFrameworkCore;
await using var context = new BloggingContext();
await context.Database.EnsureCreatedAsync();
var blog = new Blog
{
Posts =
[
new Post { Content = "This is the content of the first post."u8.ToArray() }
]
};
await context.Blogs.AddAsync(blog);
await context.SaveChangesAsync();
var blogs1 = await context.Blogs.ToListAsync();
var blogs2 = await context.Blogs
.SelectMany(b => b.Posts.Select(p => p.Content))
.ToListAsync();
var content1 = blogs1[0].Posts[0].Content;
var content2 = blogs2[0];
var decodedViaSql = await context.Database
.SqlQueryRaw<byte[]>( "SELECT decode((b.\"Posts\"->0->>'Content'), 'base64') AS \"Value\" FROM \"Blogs\" AS b LIMIT 1")
.FirstAsync();
Console.WriteLine($"content1 len={content1.Length}, bytes={string.Join(",", content1)}");
Console.WriteLine($"content2 len={content2.Length}, bytes={string.Join(",", content2)}");
Console.WriteLine($"decodedViaSql len={decodedViaSql.Length}, bytes={string.Join(",", decodedViaSql)}");
Console.WriteLine("content1 equals content2: " + content1.SequenceEqual(content2));
Console.WriteLine("content1 equals decodedViaSql: " + content1.SequenceEqual(decodedViaSql));
Console.WriteLine("content2 equals decodedViaSql: " + content2.SequenceEqual(decodedViaSql));
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs => Set<Blog>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Username=postgres;Password=password;Database=demo");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.OwnsMany<Post>(b => b.Posts, b =>
{
b.ToJson();
b.WithOwner();
});
}
}
public class Blog
{
public int BlogId { get; set; }
public List<Post> Posts { get; set; } = [];
}
public class Post
{
public required byte[] Content { get; set; }
}
Thanks for the minimal repro - I can indeed see the bug happening. It also indeed seems PG-specific (does not repro with SQL Server). I'll try to take a look at this soon.
Activity
roji commentedon Jul 4, 2025
Thanks for the minimal repro - I can indeed see the bug happening. It also indeed seems PG-specific (does not repro with SQL Server). I'll try to take a look at this soon.
drapka commentedon Dec 10, 2025
Hi @roji, just a heads up that this still reproduces in EfCore.Pg v10.
Looking into this closer, I adapted the repro code a bit to see what might be happening under the hood and this is my conclusion: