Chr*_*ray 5 c# dbcontext entity-framework-core .net-core
使用流利的api,如何在DbContext类的OnModelCreating方法内将自定义类型映射为主键?
我正在尝试使用EF Core为跟随实体建立模型。
public class Account
{
public AccountId AccountId { get; }
public string Name { get; set; }
private Account()
{
}
public Account(AccountId accountId, string name)
{
AccountId = accountId;
Name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
主键是AccountId; 类型是一个像这样的简单值对象。
public class AccountId
{
public string Id { get; }
public AccountId(string accountId)
{
Id = accountId;
}
}
Run Code Online (Sandbox Code Playgroud)
在中OnModelCreating,我发现AccountId没有后备字段就无法映射。因此,我介绍了支持领域_accountId。我不希望AccountId具有设置器。
public class Account
{
private string _accountId;
public AccountId AccountId { get { return new AccountId(_accountId); } }
public string Name { get; set; }
private Account()
{
}
public Account(AccountId accountId, string name)
{
_accountId = accountId.Id;
Name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
但是我仍然不知道如何使用后备字段(也是主键)指定属性。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var account = modelBuilder.Entity<Account>();
account.ToTable("Accounts");
account.HasKey(x => x.AccountId);
account.Property(x => x.AccountId).HasField("_accountId");
}
Run Code Online (Sandbox Code Playgroud)
OnModelCreating在属性映射行(account.Property(x => x.AccountId).HasField("_accountId");)上引发异常。说明属性和字段必须是相同的类型。
正如所指出的,通过利用EF Core 2.1中的值转换功能,可以使用自定义类型属性作为实体键
因此,在您自己的示例中,您现在可以像这样为它定义自定义转换,而不是将属性映射到支持字段:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
account.HasKey(x => x.AccountId);
account.Property(x => x.AccountId)
.HasConversion(
v => v.Id,
v => new AccountId(v));
}
Run Code Online (Sandbox Code Playgroud)
如文档中所述,还可以实现 ValueConverter 类以使转换可重用,并且还提供了许多开箱即用的自定义转换器。
注意:为您的自定义类实现IComparable和是个好主意。因为 EF Core 似乎在内部根据它们的键对更改的实体进行排序以进行批处理,如果您的键不具有可比性,您将收到异常!IComparable<T>AccountId