2015-02-24 53 views
0

我有兩個模型,其中一個ApplicationUser它擁有系統中的所有用戶,並且我有一個引用模型,它將容納所有Quotations。現在我想在Quotations裏面存儲兩個映射到ApplicationUser。這樣我就可以映射到已創建的用戶以及已取消的用戶。我的模型看起來像這樣實體框架代碼首先映射相同的實體兩次用於不同的目的

public class Quotation 
{ 
    public int QuotationID { get; set; } 
    public DateTime QuotationDate { get; set; } 
    public DateTime QuotationCancelDate { get; set; } 
    public int ApplicationUserID { get; set; } 
    public virtual ApplicationUser CreatedUser { get; set; } 
    [ForeignKey("ApplicationUserID")] 
    public ApplicationUser CancelledUser { get; set; } 

} 

但是,這會引發錯誤

Quotation_CancelledUser_Target_Quotation_CancelledUser_Source: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'ApplicationUserID' on entity 'Quotation' does not match the type of property 'Id' on entity 'ApplicationUser' in the referential constraint 'Quotation_CancelledUser'. 

所以我想,我採用的方法是錯誤的。任何人都可以指出實現這一目標的正確方法嗎?

+0

嘗試將ApplicationUserID更改爲ApplicationUserId?在屬性和外鍵屬性中。 – 2015-02-24 05:26:52

回答

1

您正在觀察的問題被稱爲「多級聯路徑」。當級聯路徑從表A的列col1到表B以及從表A的列col2到表B時發生多級聯路徑。

當代碼第一次嘗試添加表時,SQL Server引起異常列中出現多次的表格。

在SQL Server中,一個表不能在DELETE或UPDATE語句啓動的所有級聯參照操作的列表中出現多次。例如,級聯參照動作樹必須只有一條路徑到達級聯參照動作樹上的特定表。

您將需要使用FluentAPI來配置關係。我目前正在使用EF5,不知道這是否可以在EF6/7中完成。

所以修改您的代碼示例,它看起來像:

public class Quotation 
{ 
    public int QuotationID { get; set; } 
    public DateTime QuotationDate { get; set; } 
    public DateTime QuotationCancelDate { get; set; } 

    public int CreatedUserID { get; set; } 
    // Navigation property 
    public virtual ApplicationUser CreatedUser { get; set; } 

    public int CancelledUserID { get; set; } 
    // Navigation property 
    public virtual ApplicationUser CancelledUser { get; set; } 
} 

// Created a simple class for example 
public class ApplicationUser 
{ 
    [Key] 
    public int Id { get; set; } 

    public string Name { get; set; } 
} 

現在,在你的上下文類,你可以這樣寫:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Disable the default PluralizingTableNameConvention 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
     modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

     // Add configuration here 

     modelBuilder.Entity<Quotation>() 
      .HasKey(e => e.QuotationID); 

     modelBuilder.Entity<ApplicationUser>() 
      .HasKey(e => e.Id); 

     modelBuilder.Entity<Quotation>() 
         .HasRequired(a => a.CreatedUser) 
         .WithMany() 
         .HasForeignKey(u => u.CreatedUserID); 

     modelBuilder.Entity<Quotation>() 
      .HasRequired(a => a.CancelledUser) 
      .WithMany() 
      .HasForeignKey(u => u.CancelledUserID); 
    } 

欲瞭解更多信息,與例如參照此link

+0

現在,它會導致另一個錯誤.Quotation_CancelledUser_Target_Quotation_CancelledUser_Source ::參照約束的從屬角色中的所有屬性的類型必須與主體角色中的相應屬性類型相同。實體'Quotation'上的屬性'CancelledUserID'的類型與參考約束'Quotation_CancelledUser'中實體'ApplicationUser'上的屬性'Id'的類型不匹配。 Quotation_CreatedUser_Target_Quotation_CreatedUser_Source :: – Athul 2015-02-24 07:19:43

+0

參照約束的從屬角色中的所有屬性的類型必須與主角色中相應的屬性類型相同。實體'Quotation'上的屬性'CreatedUserID'的類型與參考約束'Quotation_CreatedUser'中實體'ApplicationUser'上的屬性'Id'的類型不匹配。 – Athul 2015-02-24 07:20:15

+0

使用.HasForeignKey(u => u.CreatedUserID).WillCascadeOnDelete(false); – SBirthare 2015-02-24 07:21:14