我无法正常使用后备字段,我尝试使用以下文档:https://docs.microsoft.com/en-us/ef/core/modeling/backing-field,但不走运。
当我尝试添加迁移时,遇到此错误:
属性“ Workflow._step1”的类型为“ Step1” 当前数据库提供程序不支持该功能。 更改属性CLR类型或忽略属性 使用'[NotMapped]'属性或使用'OnModelCreating'中的'EntityTypeBuilder.Ignore'。
多个工作流程可以使用同一步骤,所以我希望这样保存它
Workflow
{
Id,
Step1Id
Step2Id
}
不适用代码的示例:
public class Workflow
{
private Step1 _step1;
private Step2 _step2;
public Guid Id { get; set; } = Guid.NewGuid();
public bool Step1Enabled => true;
public Step1 Step1 => Step1Enabled ? _step1 : null;
public bool Step2Enabled => _step1.Completed;
public Step2 Step2 => _step2Enabled ? _step2 : null;
}
public class Step1
{
public Guid Id { get; set; } = Guid.NewGuid();
public bool StatusUniqueToStep1 { get; set; }
public bool Completed {get; set; }
}
public class Step2
{
public Guid Id { get; private set; } = Guid.NewGuid();
public bool StatusUniqueToStep2 { get; set; }
public bool Completed {get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) :base(options)
{}
public DbSet<Workflow> Workflows { get; set; }
// Tried adding these, does not work.
// public DbSet<Step1> Step1 { get; set; }
// public DbSet<Step2> Step2 { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Tried adding these, does not work.
// modelBuilder.Entity<Step1>();
// modelBuilder.Entity<Step2>();
modelBuilder.Entity<Workflow>()
.Property<Step1>("_step1");
modelBuilder.Entity<Workflow>()
.Property<Step2>("_step2");
}
}
答案 0 :(得分:2)
是这种情况。按照EF Core的术语,这些属性不是属性,而是导航属性,因此无法使用Property
流利的API进行配置(并且通常不会由具有Property
/ {{1}的任何元数据/条目方法返回} 在名字里)。
相反,它们是通过与关系相关的流利API进行配置的。不过,映射后备字段的问题是,没有类似于“属性”的自然流利的API,因此您必须直接使用元数据。
配置可能是这样的:
Properties
或考虑到支持字段名称遵循EF Core命名约定之一:
modelBuilder.Entity<Workflow>()
.HasOne(e => e.Step1)
.WithMany()
.Metadata.DependentToPrincipal.SetField("_step1");
modelBuilder.Entity<Workflow>()
.HasOne(e => e.Step2)
.WithMany()
.Metadata.DependentToPrincipal.SetField("_step2");
但这也是EF Core的默认行为。因此,实际的问题不是支持领域,而是EF Core默认情况下不包括只读(无设置器)属性(简单或导航,无关紧要)的事实。因此,使这项工作最少的配置是这样的:
modelBuilder.Entity<Workflow>()
.HasOne(e => e.Step1)
.WithMany()
.Metadata.DependentToPrincipal.SetPropertyAccessMode(PropertyAccessMode.Field);
modelBuilder.Entity<Workflow>()
.HasOne(e => e.Step2)
.WithMany()
.Metadata.DependentToPrincipal.SetPropertyAccessMode(PropertyAccessMode.Field);
更新:为了强制EF Core为modelBuilder.Entity<Workflow>()
.HasOne(e => e.Step1);
modelBuilder.Entity<Workflow>()
.HasOne(e => e.Step2);
(从数据库中读取)和set
(更改跟踪,存储到数据库)使用备份字段,请使用第二种配置-get
。