【发布时间】:2021-07-06 11:49:58
【问题描述】:
在 EF Core TPH 设置中使用 shared columns 时,是否可以在投影期间访问共享列?
class Program
{
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder => {
builder.AddConsole();
});
static async Task Main(string[] args)
{
using (var context = new ClientContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var actions = await context.Actions
.Select(a => new
{
Id = a.Id,
// this works - but really messy and complex in real world code
Message = (a as ActionA).Message ?? (a as ActionB).Message,
// this throws "Either the query source is not an entity type, or the specified property does not exist on the entity type."
// is there any other way to access the shared column Message?
// Message = EF.Property<string>(a, "Message"),
})
.ToListAsync();
actions.ForEach(a => Console.WriteLine(a.Id + a.Message));
}
}
public class ActionBase
{
public int Id { get; set; }
// ... other shared properties
}
public class ActionA : ActionBase
{
// shared with B
[Required]
[Column("Message")]
public string Message { get; set; }
// ... other specific properties
}
public class ActionB : ActionBase
{
// shared with A
[Required]
[Column("Message")]
public string Message { get; set; }
// ... other specific properties
}
public class ActionC : ActionBase
{
public string SomethingElse { get; set; }
// ... other specific properties
}
class ClientContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// TO USE SQL
//optionsBuilder
// .UseLoggerFactory(MyLoggerFactory)
// .UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=TPHSharedColumn;Trusted_Connection=True;MultipleActiveResultSets=true;Connect Timeout=30")
// .EnableSensitiveDataLogging(false);
// TO USE INMEMORY
optionsBuilder
.UseLoggerFactory(MyLoggerFactory)
.UseInMemoryDatabase(Guid.NewGuid().ToString());
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ActionA>().HasData(new ActionA()
{
Id = 1,
Message = "A"
});
builder.Entity<ActionB>().HasData(new ActionB()
{
Id = 2,
Message = "B"
});
builder.Entity<ActionC>().HasData(new ActionC()
{
Id = 3,
SomethingElse = "C"
});
}
public DbSet<ActionBase> Actions { get; set; }
}
}
在这个简单的示例中,当然可以将 Message 移动到基类 - 但这可能会意外添加带有 Message 的 ActionC,因为我需要删除 @ 987654326@属性。
我也知道我可以添加一个 ActionWithRequiredMessage 中间类来继承 ActionA 和 ActionB,但同样 - 在更复杂的现实世界示例中,这是不可行的,因为还有其他共享列和 C#不允许从多个类继承 - 而且 EF Core 似乎不喜欢为此使用接口。
我只是想找到一种方法来直接访问共享列 - 并在投影中使用它。
有人知道这是否可行吗?
【问题讨论】:
标签: entity-framework-core table-per-hierarchy