EF和TPT:在SET子句中多次指定列名
我正在使用EF 6并使用TPT策略来模拟我的问题。 Rule
是一个抽象类。 OvertimeRule
是一个inheritance自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().ToTable("Rules", TimmiSchemaName); modelBuilder.Entity().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId); modelBuilder.Entity().ToTable("OverTimeRules", TimmiSchemaName);
谁能告诉我什么可能触发这种行为?
这个很棘手。
modelBuilder.Entity().HasRequired(s => s.Statute).WithMany().HasForeignKey(r => r.StatuteId);
实际上是不正确的,应该是
modelBuilder.Entity().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId);
作为属性statute.Rules
存在于外键的另一侧。
没有它,EF会尝试从Rules表中自动将属性映射到sql列,他猜测应该是StatuteID
。
我在你提供的代码中看到两个奇怪的东西:
1)
modelBuilder.Entity().HasRequired(s => s.Statute)...
这部分说明Rule
要求财产Statute
,但它无处可见。 这怎么编译?
2)
modelBuilder.Entity().ToTable("Rules", TimmiSchemaName);
TPT的要点是您使用其中一个表作为抽象类,这意味着您将使用该表作为从中派生的模型。 您应该无法获取规则 ,但您可以获取作为规则的OverTimeRule
。 派生表的主键与基表完全相同的主键也很重要。 您的上下文类应如下所示:
public class MyContext : DbContext { public DbSet Rules {get; set;} protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().ToTable("OverTimeRules"); ... } }
这里真的很棒的文章: http : //weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt