2016-01-28 46 views
6

我正在使用EF 6並使用TPT策略來模擬我的問題。 Rule是一個抽象類。 OvertimeRule是一個具體的類,繼承自RuleEF和TPT:在SET子句中多次指定列名稱

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.

的映射是這樣的:

 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); 

誰能告訴我什麼可能會引發這種行爲?

+0

顯示您OvertimeRule定義請 – tede24

+0

完成。沒有什麼有趣的,看到真的在這裏.. –

回答

1

這一個很棘手。

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會嘗試將該屬性自動映射到規則表中的sql列,他猜測應該是StatuteID

+0

編輯您的帖子,而不是請,答案是答案 –

+1

我很確定我遵循這裏的指導http://stackoverflow.com/help/self-answer –

+1

哦,沒有意識到這一點解決你的問題,我的不好 –

1

我看到你提供的代碼兩件怪事:

1)

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

這部分說,物業StatuteRule是必需的,但它是無處可看。這甚至是如何編譯的?

2)

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

TPT的一點是,你用你的一個表作爲一個抽象類,這意味着您將使用該表,從它派生的車型。您應該無法獲取規則,但您可以獲取OverTimeRule其中a規則。派生表的主鍵與基表完全相同的主鍵也很重要。你的上下文類應該是這個樣子:

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

+0

1:我沒有提到它的問題,但它確實存在。 2:你說'modelBuilder.Entity ().ToTable(「Rules」,TimmiSchemaName);'是沒用的?因爲不然的話,我會尊重文章的建議:) –

+0

事實上,如果你擁有它,可能不會拋出異常或任何東西,但對於TPT,它不應該被定義。 –

相關問題