自动按约定映射加上拥有的实体
Automatic by convention mapping coupled with Owned entities
我们正在使用 ef core 3.1.6。我们的实体有两个特殊接口。
ICreated 和 IUpdated
从数据库上下文中,我们使用
自动为这些添加配置
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(typeof(ICreated).Assembly);
builder
.Model
.GetEntityTypes()
.Where(et => typeof(IUpdated).IsAssignableFrom(et.ClrType))
.ForEach(et => builder.Entity(et.ClrType).Property(nameof(IUpdated.UpdatedUTC)).IsConcurrencyToken());
builder
.Model
.GetEntityTypes()
.Where(et => typeof(ICreated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
var entity = builder
.Entity(et.ClrType);
entity
.Property(nameof(ICreated.CreatedUTC))
.IsRequired();
entity.Property(nameof(ICreated.CreatedBy))
.IsRequired();
})
}
到目前为止,这种方法运行良好。但现在我们想添加一个 ICreated
实体作为拥有的实体做
builder.OwnsOne(p => p.PayerInfo, b =>
{
b.WithOwner().HasForeignKey(p => p.PaymentTransactionId);
b.ToTable("PaymentTransactionPayerInfo", "dbo");
});
如果我们不添加 ICreated
接口,这将起作用。如果我们将接口添加到实体,它将在此行崩溃 builder.Entity(et.ClrType)
例外情况
The type 'PaymentTransactionPayerInfo' cannot be configured as
non-owned because an owned entity type with the same name already
exists
所以对于这些我需要以某种方式使用 OwnedNavigationBuilder
。想法?谢谢
由于 EF Core 不允许您使用 Entity
方法来获取实体类型生成器以与 fluent APIs 一起使用,我看到两个选项:
- 不要使用 fluent API,直接使用可变元数据 API 执行配置,例如:
builder
.Model
.GetEntityTypes()
.Where(et => typeof(IUpdated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
et.FindProperty(nameof(IUpdated.UpdatedUTC))
.IsConcurrencyToken = true;
});
builder
.Model
.GetEntityTypes()
.Where(et => typeof(ICreated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
et.FindProperty(nameof(ICreated.CreatedUTC))
.IsNullable = false;
et.FindProperty(nameof(ICreated.CreatedBy))
.IsNullable = false;
});
- 冒一点风险使用内部 API(不知道为什么他们把它变成内部 w/o 提供一种 public 获得所需构建器的方法)。
添加
using Microsoft.EntityFrameworkCore.Metadata.Internal;
这将使您能够访问 AsEntityType()
扩展方法,并且返回的类型具有 属性 Builder
返回流畅调用所需的实体类型构建器:
builder
.Model
.GetEntityTypes()
.Where(et => typeof(IUpdated).IsAssignableFrom(et.ClrType))
.ForEach(et => et.AsEntityType().Builder // <--
.Property(nameof(IUpdated.UpdatedUTC)).IsConcurrencyToken());
builder
.Model
.GetEntityTypes()
.Where(et => typeof(ICreated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
var entity = et.AsEntityType().Builder; // <--
entity
.Property(nameof(ICreated.CreatedUTC))
.IsRequired();
entity.Property(nameof(ICreated.CreatedBy))
.IsRequired();
});
我们正在使用 ef core 3.1.6。我们的实体有两个特殊接口。
ICreated 和 IUpdated
从数据库上下文中,我们使用
自动为这些添加配置protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(typeof(ICreated).Assembly);
builder
.Model
.GetEntityTypes()
.Where(et => typeof(IUpdated).IsAssignableFrom(et.ClrType))
.ForEach(et => builder.Entity(et.ClrType).Property(nameof(IUpdated.UpdatedUTC)).IsConcurrencyToken());
builder
.Model
.GetEntityTypes()
.Where(et => typeof(ICreated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
var entity = builder
.Entity(et.ClrType);
entity
.Property(nameof(ICreated.CreatedUTC))
.IsRequired();
entity.Property(nameof(ICreated.CreatedBy))
.IsRequired();
})
}
到目前为止,这种方法运行良好。但现在我们想添加一个 ICreated
实体作为拥有的实体做
builder.OwnsOne(p => p.PayerInfo, b =>
{
b.WithOwner().HasForeignKey(p => p.PaymentTransactionId);
b.ToTable("PaymentTransactionPayerInfo", "dbo");
});
如果我们不添加 ICreated
接口,这将起作用。如果我们将接口添加到实体,它将在此行崩溃 builder.Entity(et.ClrType)
例外情况
The type 'PaymentTransactionPayerInfo' cannot be configured as non-owned because an owned entity type with the same name already exists
所以对于这些我需要以某种方式使用 OwnedNavigationBuilder
。想法?谢谢
由于 EF Core 不允许您使用 Entity
方法来获取实体类型生成器以与 fluent APIs 一起使用,我看到两个选项:
- 不要使用 fluent API,直接使用可变元数据 API 执行配置,例如:
builder
.Model
.GetEntityTypes()
.Where(et => typeof(IUpdated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
et.FindProperty(nameof(IUpdated.UpdatedUTC))
.IsConcurrencyToken = true;
});
builder
.Model
.GetEntityTypes()
.Where(et => typeof(ICreated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
et.FindProperty(nameof(ICreated.CreatedUTC))
.IsNullable = false;
et.FindProperty(nameof(ICreated.CreatedBy))
.IsNullable = false;
});
- 冒一点风险使用内部 API(不知道为什么他们把它变成内部 w/o 提供一种 public 获得所需构建器的方法)。
添加
using Microsoft.EntityFrameworkCore.Metadata.Internal;
这将使您能够访问 AsEntityType()
扩展方法,并且返回的类型具有 属性 Builder
返回流畅调用所需的实体类型构建器:
builder
.Model
.GetEntityTypes()
.Where(et => typeof(IUpdated).IsAssignableFrom(et.ClrType))
.ForEach(et => et.AsEntityType().Builder // <--
.Property(nameof(IUpdated.UpdatedUTC)).IsConcurrencyToken());
builder
.Model
.GetEntityTypes()
.Where(et => typeof(ICreated).IsAssignableFrom(et.ClrType))
.ForEach(et =>
{
var entity = et.AsEntityType().Builder; // <--
entity
.Property(nameof(ICreated.CreatedUTC))
.IsRequired();
entity.Property(nameof(ICreated.CreatedBy))
.IsRequired();
});