c# - 如何定义一个字段 ONCE,然后在多个实体中使用该定义?
问题描述
我正在使用类继承来添加我的所有实体都必须包含的一组基本字段。当我这样做时,EF Core 会尊重基类中存在的任何数据注释,例如[TimeStamp]
,在从它继承的类上:
public class SomeClass : BaseEntity
{
public string SomeEntityField { get; set; }
}
public class BaseEntity
{
public int Id { get; set; }
public DateTimeOffset UpdatedDate { get; set; }
public DateTimeOffset CreatedDate { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
当我想添加所有继承的字段时,上述内容很棒。
但是,如果我希望能够创建一个字段定义 ONCE,然后在其他几个实体中使用该定义,同时还从基类(上面)继承呢?
假设我有这个实体,ItemType
:
public class ItemType : BaseEntity
{
[StringLength(28)]
public string ItemTypeId { get; set; }
...
我希望能够ItemTypeId
在一个地方定义该字段,然后在包括上表在内的多个实体上使用它,而不必在所有这些实体中手动添加/维护注释。例如,如果我需要使字段更宽[StringLength(50)]
,我会在一个地方对其进行调整,然后在下一次迁移时更新所有相关字段,因为它们都从相同的定义中“读取”。我试过了
- 使用接口,但 EF 不支持接口上的数据注释。
- 多重继承,但不能使用,因为我可能需要多个“一次性”字段(并且接口不能按照 #1 工作)
根据CS1721,什么都行不通(好吧,除了单个基类本身)。
我认为理想情况下我希望能够在CommonFieldType
下面的代码中定义实体字段,然后让目标实体从它们继承,但不幸的是,由于上述原因,这不起作用。
namespace RDCApp.Shared.CommonFieldType
{
public abstract class ItemTypeIdCFT
{
[StringLength(28)]
public string ItemTypeId { get; set; }
}
public abstract class AnotherCFT
{
[StringLength(100)]
public string AnotherField { get; set; }
}
...
我不能成为唯一需要/想要这个的人,所以还有其他方法吗?
我知道可以使用 Fluent API,但是我的项目对数据注释的投入如此之大,以至于使用它(以及)感觉不对,这意味着我有 2 个地方可以查看和定义字段属性。直接针对 POCO 进行定义对我来说是正确的!
编辑 为了限定“我觉得正确”的含义:我的 VS 解决方案包括服务器(ASP.NET Core)和客户端(Blazor WASM)项目。两个层都可以“看到”共享项目中的实体/POCO,并且两个层都需要知道注释是什么来执行验证。这意味着我只需要定义一次验证/属性,然后两层都可以看到这一点。
对我来说,Fluent 不是一个合适的选择——尽管如果这是一个典型的服务器端应用程序,我会为 Fluent 拍摄。
解决方案
您可以定义一个接口和一个通用的 fluent api 帮助器方法来定义字段。
public interface IHasItemType{
int ItemTypeId { get; set; }
}
public void DefineItemType<T> (EntityTypeBuilder<T> builder) where T:IHasItemType{
builder.Property(i => i.ItemTypeId) ...
}
或者你可以应用约定OnModelCreating
foreach (var table in modelBuilder.Model.GetEntityTypes())
{
foreach (var column in table.GetProperties())
{
// ...
}
}
推荐阅读
- nlp - 我想构建一个下一个单词预测器,但我希望它不仅仅使用 n-gram。我有什么方法可以做到这一点?
- r - 如何从R中的另一个数据框中提取值
- nginx - 入口 nginx 从 www 重定向到 https
- java - 从 svg 中删除转换或从 SVG 路径中获取 Java awt 组件
- python - 更改 models.py 中属性的数据类型后,Django 迁移未在 Postgres 上应用
- c++ - 如何在 C++ 中使用默认值将 std::set 转换为 std::map
- javascript - 如何使用 jquery 渲染部分内容?
- javascript - 按顺序大写字符串中的字母并创建一个数组来存储
- twilio - 我可以使用 Twilio Flow 呼叫一组销售团队号码,等待其中一个人接听,然后呼叫新的潜在客户并连接这两个号码吗?
- c# - 我可以强制子类实现接口吗?