2017-03-07 80 views
1

我試圖創建一個關係公司的數據模型,首先在實體框架代碼中的相同類型。我想單向創建關係,所以當一家公司增加另一個作爲其客戶時,另一家公司不會自動將該公司作爲供應商。實體框架中的同一類的多個列表

public class Company { 
    [Key] 
    public string Id { set; get; } 
    public string Name { set; get; } 

    public virtual ICollection<Company> Customers { set; get; } 
    public virtual ICollection<Company> Suppliers { set; get; } 
} 

當我像這樣更新數據庫時,我最終得到一個名爲「CompanyCompanies」的連接表。

CompanyCompanies

| Company_Id | Company_Id1 | 
|------------|-------------| 
| 1234  | 1234  | 

我要創建兩個表來連接這些值,就像這樣:

CompanyCustomers

| Company_Id | Customer_Id | 
|------------|-------------| 
| 1234  | 1234  | 

CompanySuppliers

| Company_Id | Supplier_Id | 
|------------|-------------| 
| 1234  | 1234  | 

我已經看了很多流利的API,並試圖定義那裏的關係,但我似乎無法得到我的頭如何做到這一點。我發現了很多使用不同實體的例子,但只有this answer與自身的關係。但是,當我從該問題實施解決方案並更新數據庫時,出現連接超時的錯誤。

modelBuilder.Entity<Company>() 
    .HasMany(c => c.Customers) 
    .WithMany() 
    .Map(m => 
    { 
     m.ToTable("CompanyCustomer"); 
     m.MapLeftKey("CompanyId"); 
     m.MapRightKey("CustomerId"); 
    }); 

錯誤編號:-2,狀態:0,類別:11 執行超時過期。
完成操作或服務器沒有響應之前超時時間已過。

當我試着使用這兩個CompanyCustomer和CompanySupplier我得到antoher錯誤

無論是參數@objname不明確或所要求的@objtype(列)是錯誤的。

我也嘗試爲關係創建一個新對象,並讓Company對象擁有CompanyCustomers的列表,但是當我用這個更新數據庫時,我得到了一個包含三列的連接表。

public class CompanyCustomer 
{ 
    [Key, Column(Order = 0)] 
    [ForeignKey("Company")] 
    public string CompanyId { set; get; } 
    [Key, Column(Order = 1)] 
    [ForeignKey("Customer")] 
    public string CustomerId { set; get; } 

    public virtual Company Company { set; get; } 
    public virtual Company Customer { set; get; } 
} 

CompanyCustomer

| CompanyId | CustomerID | Company_Id | 
|-----------|------------|------------| 
| 1234  | 1234  | 1234  | 

我不明白我怎麼能建立同樣的實體之間的一些關係類型。我可以在流利的api幫助下做到這一點,還是必須重新設計我的模型?

+1

超時並不意味着模型不正確,只是遷移需要很多時間來執行DDL語句。從技術上講,這兩個'HasMany - WithMany'配置應該可以。 –

+1

當你說你做了隱式的'many-to-many'配置(使用'.HasMany(c => c.Customers).WithMany()',你是否對其他關係'CompanySuppliers'做了同樣的事情?當我這樣做,並看看生成的遷移,這正是你想要的。 –

+0

我更新了我的問題伊凡。我只有在收集其中一個時纔得到超時。當我嘗試使用兩種方法時,出現錯誤,說@objname是ambigous ... –

回答

1

流利的配置

modelBuilder.Entity<Company>() 
    .HasMany(c => c.Customers) 
    .WithMany() 
    .Map(m => 
    { 
     m.ToTable("CompanyCustomer"); 
     m.MapLeftKey("CompanyId"); 
     m.MapRightKey("CustomerId"); 
    }); 

確實構成第一關係的正確途徑。你需要做的類似第二:

modelBuilder.Entity<Company>() 
    .HasMany(c => c.Suppliers) 
    .WithMany() 
    .Map(m => 
    { 
     m.ToTable("CompanySupplier"); 
     m.MapLeftKey("CompanyId"); 
     m.MapRightKey("SupplierId"); 
    }); 

這在我的乾淨的EF測試環境(如果該事項最新EF6.1.3)產生以下遷移:

CreateTable(
    "dbo.Company", 
    c => new 
     { 
      Id = c.String(nullable: false, maxLength: 128), 
      Name = c.String(), 
     }) 
    .PrimaryKey(t => t.Id); 

CreateTable(
    "dbo.CompanyCustomer", 
    c => new 
     { 
      CompanyId = c.String(nullable: false, maxLength: 128), 
      CustomerId = c.String(nullable: false, maxLength: 128), 
     }) 
    .PrimaryKey(t => new { t.CompanyId, t.CustomerId }) 
    .ForeignKey("dbo.Company", t => t.CompanyId) 
    .ForeignKey("dbo.Company", t => t.CustomerId) 
    .Index(t => t.CompanyId) 
    .Index(t => t.CustomerId); 

CreateTable(
    "dbo.CompanySupplier", 
    c => new 
     { 
      CompanyId = c.String(nullable: false, maxLength: 128), 
      SupplierId = c.String(nullable: false, maxLength: 128), 
     }) 
    .PrimaryKey(t => new { t.CompanyId, t.SupplierId }) 
    .ForeignKey("dbo.Company", t => t.CompanyId) 
    .ForeignKey("dbo.Company", t => t.SupplierId) 
    .Index(t => t.CompanyId) 
    .Index(t => t.SupplierId); 

這正是你想。

你得到的例外情況如何,它們可能與你對數據庫的實驗有關。確保從清潔數據庫開始或刪除Company實體(如果它存在CompanyCustomer) ,對應DbSet s和流暢配置,更新數據庫以清理以前的混亂並再試一次。

0

你可以用屬性來做到這一點。你的問題是你在錯誤的屬性上使用[ForeignKey]屬性 - 它應該在導航屬性上。

[ForeignKey(nameof(CompanyId))] 
public virtual Company Company { set; get; } 

[ForeignKey(nameof(CustomerId))] 
public virtual Company Customer { set; get; } 

此外,您可以將[InverseProperty]屬性添加到模型上的集合。這有助於理解關係導航。

[InverseProperty(nameof(CompanyCustomer.Company))] 
public virtual ICollection<Company> Customers { set; get; } 
+0

謝謝,但我真的很想避免爲這個關係創建一個新的類。有沒有辦法解決這個問題? –

+0

爲什麼要避開新的類?個人而言,我發現比使用煙道更容易理解和擴展nt api。 –

相關問題