繁体   English   中英

EF和TPT:在SET子句中多次指定列名

[英]EF and TPT : the column name is specified more than once in the SET clause

我正在使用EF 6,并使用TPT策略对问题进行建模。 Rule是一个抽象类。 OvertimeRule是一个具体的类,继承自Rule

Rule看起来像这样:

public abstract class Rule
{   
    public int Id { get; set; }
    public PeriodType PeriodType { get; set; }
    public int SortOrder { get; set; }
    public int StatuteId { get; set; }
    public bool IsActive { get; set; }
}

OvertimeRule看起来像这样:

public partial class OvertimeRule : Rule
{
    public decimal? ThresholdCoefficient { get; set; }
    public decimal? LimitCoefficient { get; set; }
}

当我创建一个新的OvertimeRule并尝试保存它时,EF首先生成此查询:

INSERT [dbo].[Rules]([PeriodType], [SortOrder], [StatuteId], [IsActive], [StatuteID])
VALUES (@0, @1, @2, @3, @4, @5, @6, NULL)

如您所见,EF将StatuteID列添加到插入中,该列在解决方案中不存在,并使该列成为无效的SQL查询。

然后,SQL正确地抛出: The column name 'StatuteId' is specified more than once in the SET clause. A column cannot be assigned more than one value in the same SET clause. Modify the SET clause to make sure that a column is updated only once. If the SET clause updates columns of a view, then the column name 'StatuteId' may appear twice in the view definition. The column name 'StatuteId' is specified more than once in the SET clause. A column cannot be assigned more than one value in the same SET clause. Modify the SET clause to make sure that a column is updated only once. If the SET clause updates columns of a view, then the column name 'StatuteId' may appear twice in the view definition.

映射如下所示:

        modelBuilder.Entity<Rule>().ToTable("Rules", TimmiSchemaName);
        modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId);
        modelBuilder.Entity<OvertimeRule>().ToTable("OverTimeRules", TimmiSchemaName);

谁能告诉我是什么会触发这种行为?

这个很棘手。

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany().HasForeignKey(r => r.StatuteId);

实际上是不正确的,应该已经

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId);

作为属性statute.Rules存在于外键的另一侧。

如果没有它,EF会尝试将属性自动映射到Rules表中的sql列,他猜测应该是StatuteID

我在您提供的代码中看到了两个奇怪的事情:

1)

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute)...

这部分说Rule需要属性Statute ,但是无处可寻。 怎么编译?

2)

modelBuilder.Entity<Rule>().ToTable("Rules", TimmiSchemaName);

TPT的要点是,您将一个表用作抽象类,这意味着您将使用该表作为派生自该表的模型。 你不应该能够获取一个规则 ,但是你可以获取一个OverTimeRule一个规则。 派生表的主键与基表完全相同的主键也很重要。 您的上下文类应如下所示:

public class MyContext : DbContext
{
    public DbSet<Rule> Rules {get; set;}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<OverTimeRule>().ToTable("OverTimeRules");
        ...
    }
}

真正很棒的文章: http : //weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM