[英]The column name 'phoneNumber' is specified more than once in the SET clause
[英]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.