[英]EF core entity Id as custom class with identity column
我想在我的实体 model 中使用强类型 ID,映射到 DB 中的自动递增int(例如 MS SQL Identity 列)。 但 EF Core 3.1 不支持自定义类型的标识:
public class Vendor
{
public VendorId Id { get; private set; }
public string CompanyName { get; set; }
}
public class VendorId
{
public int Value { get; }
public VendorId(int value)
{
Value = value;
}
}
public void Configure(EntityTypeBuilder<Vendor> vendorEntity)
{
vendorEntity.HasKey(vendor => vendor.Id);
vendorEntity.Property(vendor => vendor.Id)
.HasConversion(vendorId => vendorId.Value, dbValue => new VendorId(dbValue))
.UseIdentityColumn();
}
有了这个 model 我得到异常:
标识值生成不能用于实体类型“供应商”上的属性“Id”,因为该属性类型是“供应商Id”。 标识值生成只能与签名的 integer 属性一起使用。
我还尝试将 map 转换为私有 integer 支持字段int id
,但后来我无法在 EF 查询中使用 Id 属性。 所以它看起来不是一个解决方案。
类似的问题是当我尝试 HiLo 密钥生成时。
您对如何解决这个问题有任何想法吗?
我使用 c# 9 记录的解决方案(在 ef 核心 5 中):
public abstract record StronglyTypedId<TValue>(TValue Value) where TValue : notnull
{
public override string ToString() => Value.ToString();
}
带有抽象实体 model:
public abstract class Entity<TId, T> where TId: StronglyTypedId<T>
{
T _Id;
public virtual TId Id
{
get { return (TId)Activator.CreateInstance(typeof(TId), new object[] {_Id}); }
}
}
然后是一个示例实体 model
using TId = Int32;
public record EntityTypeId(TId Value) : StronglyTypedId<TId>(Value);
public class EntityName<EntityTypeId, TId>
{
private EntityName() {} //for ef core
}
然后在 model 构建器中(它可以再次是抽象/基础 model 构建器)
builder.Ignore(e => e.Id);
builder
.Property("_Id")
.HasColumnName("Id")
.UseIdentityColumn();
builder.HasKey("_Id");
这确实意味着从数据库(通过命令或存储库)检索时,您需要使用名称,例如
public async Task<EntityName> GetEntity(EntityTypeId typedId)
{
var entity = await context.EntityName
.FirstOrDefaultAsync(x => EF.Property<int>(x, "_Id") == typedId.Value);
return entity;
}
不完美但有效
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.