使用流畅的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;
}
}
主键是AccountId
;类型是一个像这样的简单值对象。
public class AccountId
{
public string Id { get; }
public AccountId(string accountId)
{
Id = accountId;
}
}
在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;
}
}
但我仍然无法弄清楚如何使用支持字段指定属性,这也是主键。
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");
}
OnModelCreating在属性地图行(account.Property(x => x.AccountId).HasField("_accountId");
)上抛出异常。
声明属性和字段必须是同一类型。
答案 0 :(得分:2)
如前所述,可以利用 EF Core 2.1
中的 Value Conversion 功能将自定义类型的属性用作实体键。因此,在您自己的示例中,您无需像下面那样将属性映射到支持字段,就可以为它定义自定义转换:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
account.HasKey(x => x.AccountId);
account.Property(x => x.AccountId)
.HasConversion(
v => v.Id,
v => new AccountId(v));
}
如documentation中所述,还可以实现ValueConverter类以使转换可重用,并且还提供了许多自定义转换器。
注意:为自定义IComparable
类实现IComparable<T>
和AccountId
是一个好主意。因为EF Core似乎会在内部根据更改后的实体的键对您更改的实体进行排序,并且如果您的键不具有可比性,您将收到异常!