c# - EF Core:抽象类作为根实体处理
问题描述
我使用 EF 核心来创建我的表(代码优先),并且我在某些实体的抽象基类中遇到了奇怪的行为。我将该类ConfigurableDiscount
作为抽象基类和从它继承的多个类,例如:AfterSalesCoverage
. 这些类看起来像这样:
public abstract class ConfigurableDiscount : TenantEntity, TraceChangesEntity
{
public DealType DealType { get; set; }
[Required]
[Column(TypeName = "decimal(18,4)")]
public decimal Discount { get; set; }
}
public class AfterSalesCoverage : ConfigurableDiscount
{
public Guid Id { get; set; }
[Required]
public string Name { get; set; }
}
和分别是另一个抽象类和一个空接口TenantEntity
。TraceChangesEntity
public abstract class TenantEntity : BaseDeleteEntity
{
public Guid BusinessUnitId { get; set; }
public virtual BusinessUnit BusinessUnit { get; set; }
}
public abstract class BaseDeleteEntity : BaseEntity
{
public DateTime? DeletedOn { get; set; }
}
public abstract class BaseEntity
{
[Required]
public DateTime CreatedOn { get; set; }
public Guid CreatedById { get; set; }
public virtual User CreatedBy { get; set; }
public DateTime? ChangedOn { get; set; }
public Guid? ChangedById { get; set; }
public virtual User ChangedBy { get; set; }
}
如您所见,所有这些都是抽象的,除了AfterSalesCoverage
. 如果我尝试构建或迁移,我会收到以下错误:
实体类型“ConfigurableDiscount”需要定义一个主键。
如果我这样做(在内部定义一个虚拟键ConfigurableDiscount
或将Id
from转换AfterSalesCoverage
为ConfigurableDiscount
)并尝试迁移,我会收到以下错误:
无法为实体类型“AfterSalesCoverage”指定过滤器表达式“entity => (entity.DeletedOn == null)”。过滤器只能应用于层次结构中的根实体类型。
这让我想知道为什么 AfterSalesCoverage 不是根实体?过滤器表达式在 DBContext 中定义/配置。
编辑:
DBContext 中的过滤器在内部调用,OnModelCreating(ModelBuilder builder)
如下所示:
private void SetSoftDeleteFilterQuery(ModelBuilder builder)
{
System.Collections.Generic.IEnumerable<Type> q = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.IsSubclassOf(typeof(BaseDeleteEntity))
select t;
foreach (Type type in q)
{
MethodInfo method = typeof(CPEDbContext).GetMethod("ApplySoftDeleteFilterQuery", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo generic = method.MakeGenericMethod(type);
if (type.Name != "RequestWrapper" && type.Name != "TenantEntity" && type.Name != "BaseBenchmarkDiscount")
{
{
generic.Invoke(this, new[] { builder });
}
}
}
}
private void ApplySoftDeleteFilterQuery<Tdb>(ModelBuilder builder) where Tdb : BaseDeleteEntity
{
builder.Entity<Tdb>().HasQueryFilter(entity => entity.DeletedOn == null);
}
在这种情况下,这个过滤器似乎是关注的中心......
问题:
为什么ConfigurableDiscount
需要主键?它不应该是一个实际的实体。如果直接从 继承TenantEntity
,我也不需要 TenantEntity 中的 ID ...该ConfigurableDiscount
实体在继承类中无处引用。所以我的 DBContext 中没有 DBSet 或类似的东西。
解决方案
推荐阅读
- ios - 斯威夫特:配件问题
- javascript - 如何在浏览器的新标签页上显示 Base64 图像?
- react-native - 反应导航,获取嵌套路线的名称
- pandas - 将样式应用于索引标签和列标签熊猫数据框
- javascript - 我想了解 javascript 中的 If 速记应用
- c++ - 为什么当转换为 long int 时,对应于整数的乘法双精度会减一?
- reactjs - 套接字在其他组件中启动连接
- python-3.x - 需要解释以下代码(Python)
- python - 在 RASA 聊天响应中获取点而不是连字符
- tensorflow - Tensorflow Keras 形状不匹配