Projectable property not include in query result without select
With Projectable attr, I can select the property direct via Select and/or use as judgement. But directly query the set will not include projectable property.
Env: .net6/EFcore7
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq.Expressions;
using EntityFrameworkCore.Projectables;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
var connection = new SqliteConnection("Filename=:memory:");
connection.Open();
var contextOptions = new DbContextOptionsBuilder<AppDbContext()
.UseSqlite(connection)
.UseProjectables()
.Options;
using (var context = new AppDbContext(contextOptions))
{
context.Database.EnsureCreated();
context.Users.Add(new UserEntity
{
Id = 1,
Name = "Name",
Orders = new List<OrderEntity> { new() { Id = 1, Amount = 10 }, new() { Id = 2, Amount = 20 } }
});
await context.SaveChangesAsync();
}
using (var context = new AppDbContext(contextOptions))
{
UserEntity user;
user = await context.Users.FirstAsync(x => x.Count1 == 2);
Debug.Assert(user != null);
user = await context.Users.FirstAsync(x => x.Count2 == 2);
Debug.Assert(user != null);
user = await context.Users.FirstAsync(x => x.Count3 == 2);
Debug.Assert(user != null);
int count;
count = await context.Users.Select(x => x.Count1).FirstAsync();
Debug.Assert(count == 2);
count = await context.Users.Select(x => x.Count2).FirstAsync();
Debug.Assert(count == 2);
count = await context.Users.Select(x => x.Count3).FirstAsync();
Debug.Assert(count == 2);
user = await context.Users.FirstAsync();
if (user.Count1 != 2) { Console.WriteLine("Failed: Count1"); }
if (user.Count2 != 2) { Console.WriteLine("Failed: Count2"); }
if (user.Count3 != 2) { Console.WriteLine("Failed: Count3"); }
}
public class UserEntity
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty(nameof(OrderEntity.User))]
public ICollection<OrderEntity> Orders { get; init; } = new List<OrderEntity>(0);
[NotMapped]
[Projectable]
public int Count1 => Orders.Count;
[NotMapped]
[Projectable(UseMemberBody = nameof(InternalCount2))]
public int Count2 { get; set; }
private int InternalCount2 => Orders.Count;
[NotMapped]
[Projectable(UseMemberBody = nameof(InternalCount3))]
public int Count3 { get; set; }
private static Expression<Func<UserEntity, int>> InternalCount3 => u => u.Orders.Count;
}
public class OrderEntity
{
[Key]
public int Id { get; set; }
public int UserId { get; set; }
public int Amount { get; set; }
[ForeignKey(nameof(UserId))]
[InverseProperty(nameof(UserEntity.Orders))]
public virtual UserEntity User { get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<UserEntity> Users { get; set; }
public DbSet<OrderEntity> Orders { get; set; }
}
We've seen this as well, but haven't been that affected by it, as we use a mapper that always selects the desired attributes. But yes, it's strange. Also on .NET 6 / EF Core 7, but the same behaviour was there before aswell.
This is a known issue, a partial fix has been implemented with #86. I'm currently working on a more comprehensive fix that should go out as a larger update that will target EF 8 and above.
Hello @koenbeuk Just checking for any update about this issue.