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

C# EF和TPT:在SET子句中多次指定列名,c#,sql-server,entity-framework,inheritance,C#,Sql Server,Entity Framework,Inheritance,我使用EF 6并使用TPT策略来模拟我的问题。 规则是一个抽象类OvertimeRule是一个具体的类,继承自Rule 规则如下所示: public abstract class Rule { public int Id { get; set; } public PeriodType PeriodType { get; set; } public int SortOrder { get; set; } public int StatuteId { get;

我使用EF 6并使用TPT策略来模拟我的问题。
规则
是一个抽象类
OvertimeRule
是一个具体的类,继承自
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; }
}
public partial class OvertimeRule : Rule
{
    public decimal? ThresholdCoefficient { get; set; }
    public decimal? LimitCoefficient { get; set; }
}
OvertimeRule
如下所示:

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; }
}
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向insert中添加了一个
StatuteID
列,该列在解决方案中的任何位置都不存在,这使得这是一个无效的SQL查询

SQL然后正确地抛出:
SET子句中多次指定了列名“StatuteId”。在同一SET子句中,不能为列分配多个值。修改SET子句以确保列只更新一次。如果SET子句更新视图的列,则列名“StatuteId”可能会在视图定义中出现两次。

映射如下所示:

        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().ToTable(“规则”,名称);
modelBuilder.Entity().HasRequired(s=>s.Statute)。带有许多(s=>s.Rules)。HasForeignKey(r=>r.StatuteId);
modelBuilder.Entity().ToTable(“OverTimeRules”,timmisemaname);
有谁能告诉我是什么触发了这种行为吗?

这是一个棘手的问题

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany().HasForeignKey(r => r.StatuteId);
modelBuilder.Entity();
实际上是不正确的,应该是这样的

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId);
modelBuilder.Entity().HasRequired(s=>s.Statute)。带有许多(s=>s.Rules)。HasForeignKey(r=>r.StatuteId);
因为属性
规约规则
存在于外键的另一侧


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

我在您提供的代码中看到两个奇怪的东西:

(一)

TPT的要点是,您使用一个表作为抽象类,这意味着您将使用该表作为从中派生的模型。您应该无法获取规则,但可以获取属于规则的
OverTimeRule
。同样重要的是,派生表的主键与基表的主键完全相同。您的上下文类应该如下所示:

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

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<OverTimeRule>().ToTable("OverTimeRules");
        ...
    }
}
公共类MyContext:DbContext
{
公共数据库集规则{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().ToTable(“OverTimeRules”);
...
}
}

这里有一篇很棒的文章:

请展示您的超时规则定义。这里没有什么有趣的东西请改为编辑你的帖子,答案是为了回答我很确定我遵循了这里的指导原则哦,我不知道这解决了你的问题,我的宝贝1:我在问题中没有提到,但它确实存在。2:您的意思是
modelBuilder.Entity().ToTable(“Rules”,timmisemaname)是无用的吗?因为除此之外,我尊重文章的建议:)事实上,如果您有异常,可能不会抛出异常或任何东西,但对于TPT,它不应该被定义。