1

我已經查看了類似錯誤的答案,但似乎無法找到對特定答案的答案錯誤。導航屬性Project.Models.Customer.SubCustomers的聲明類型與指定導航的結果不兼容

我運行了遷移,並且當種子法運行(遷移一直很好)錯誤發生。

導航屬性Project.Models.Customer.SubCustomers的聲明類型與指定導航的結果不兼容。

這是一個循環引用,即客戶可以有0 .. * SubCustomers和0..1 ParentCustomers。

客戶模式:

public class Customer : Entity 
{ 
    public int CustomerId { get; set;} 
    public string Name { get; set; } 

    // Relationships 

    public int? ParentCustomerId { get; set; } 
    public virtual ICollection<Customer> SubCustomers { get; set; } // a Customer has many Customers as SubCustomers, a Customer has zero or one ParentCustomer 

    // Other relationships 
} 

從上下文流利的API:

modelBuilder.Entity<Customer>() 
      .HasKey(customer => customer.CustomerId); 
modelBuilder.Entity<Customer>() 
      .Property(customer => customer.Name) 
      .IsRequired() 
      .HasColumnType("nvarchar") 
      .HasMaxLength(500); 
modelBuilder.Entity<Customer>() // a Customer has many Customers as SubCustomers, a Customer has zero or one ParentCustomer 
      .HasOptional(customer => customer.SubCustomers) 
      .WithMany() 
      .HasForeignKey(customer => customer.ParentCustomerId); 

從播種方法:(客戶在數據庫中創建,分客戶不工作)

// Default Customers - create and save 
var customers = new[]{ 
    new Customer { Name = "Custa" }, 
    new Customer { Name = "Custb" }, 
    new Customer { Name = "Custc" } 
}; 
context.Customers.AddOrUpdate(r => r.Name, customers[0], customers[1], customers[2]); 
context.SaveChanges(); 

// Add SubCustomers b & c to Customer a (ids calculated beforehand, e.g. aId, as linq does not support array index) 
var aId = customers[0].CustomerId; 
var a = context.Customers.Include(c => c.SubCustomers).SingleOrDefault(c => c.CustomerId == aId); 
if (a.SubCustomers == null) 
    a.SubCustomers = new List<Customer>(); 
var bId = customers[1].CustomerId; 
var b = a.SubCustomers.SingleOrDefault(c => c.CustomerId == bId); 
if (b == null) 
    a.SubCustomers.Add(context.Customers.Single(c => c.CustomerId == bId)); 
var cId = customers[2].CustomerId; 
var c = a.SubCustomers.SingleOrDefault(c => c.CustomerId == cId); 
if (c == null) 
    a.SubCustomers.Add(context.Customers.Single(c => c.CustomerId == cId)); 
context.SaveChanges(); 

如果有人能夠發現導致錯誤的原因,我將非常感激。非常感謝!

回答

1

所以最後一點閱讀和反覆試驗後想通了這一點。我感到困惑,因爲它是自我引用的,而忽略了一個關鍵因素。

通常情況下,創造了一個一對多的關係,兩個不同對象之間的時候,你會像下面這樣:

public class Foo { 
    public int FooId {get; set;} 
    public string Name {get; set;} 

    // Relationships 
    public virtual ICollection<Bar> Bars {get; set;} // a Foo has many bars, a Bar has one optional Foo 
} 

public class Bar { 
    public int BarId {get; set;} 
    public string Name {get; set;} 

    // Relationships 
    public int? FooId {get; set;} // a Foo has many bars, a Bar has one optional Foo 
    public virtual Foo Foo {get; set;} 
} 
在上下文

然後(流利API):

modelBuilder.Entity<Bar>() // a Foo has many bars, a Bar has one optional Foo 
    .HasRequired(bar => bar.Foo) 
    .WithMany(foo => foo.Bars) 
    .HasForeignKey(bar => bar.FooId); 
modelBuilder.Entity<Bar>() 
      .HasKey(bar => bar.BarId); 

modelBuilder.Entity<Foo>() 
      .HasKey(foo => foo.FooId); 

在我的代碼中,在我的原始問題中,在這種情況下,我忽略了public virtual Foo Foo {get; set;}的等效項。

所以創建一個自引用美孚你需要的關係,所有的三個要素,即是在例如兩個物體之間的分裂以上,是在Foo對象(漂亮的邏輯真的!):

public class Foo { 
    public int FooId {get; set;} 
    public string Name {get; set;} 

    // Relationships 
    public int? ParentFooId {get; set;} // a Foo has many SubFoos, a Foo has one optional ParentFoo 
    public virtual Foo ParentFoo {get; set;} 
    public virtual ICollection<Foo> SubFoos {get; set;} 
} 

和上下文(流利API):

modelBuilder.Entity<Foo>() // a Foo has many SubFoos, a Foo has one optional ParentFoo 
    .HasOptional(foo => foo.ParentFoo) 
    .WithMany(foo => foo.SubFoos) 
    .HasForeignKey(foo => foo.ParentCustomerId); 
modelBuilder.Entity<Foo>() 
      .HasKey(foo => foo.FooId); 

種子數據到這個自參照關係,我需要在Configuration.cs如下:

// Default Foos - create 
var foos = new[]{ 
     new Foo { Name = "foo1", SubFoos = new List<Foo>() }, 
     new Foo { Name = "foo2", SubFoos = new List<Foo>() }, 
     new Foo { Name = "foo3", SubFoos = new List<Foo>() },   
context.Tabs.AddOrUpdate(t => t.View, foos[0], foos[1], foos[2]); 
context.SaveChanges(); 

// Add a SubFoo to a Foo 
var parentFooId = foos[0].FooId; 
var parentFoo = context.Foos.Include(f => f.SubFoos).SingleOrDefault(f => f.FooId == parentFooId); 
// If no current SubFoos initiate an empty list 
if (parentFoo.SubFoos == null) 
    parentFoo.SubFoos = new List<Foo>(); 
// Get another Foo to add as a SubFoo 
var childFooId = foos[1].FooId; 
// Check if child foo already exists and add if not 
var childFoo = parentFoo.SubFoos.SingleOrDefault(f => f.FooId == childFooId); 
if (childFoo == null) 
    parentFoo.SubFoos.Add(context.Foos.Single(f => f.FooId == childFooId)); 
context.SaveChanges(); 
+0

感謝您發表該問題和答案。今天早上我們一直在爲這個確切的問題奮鬥了幾個小時,這是我們指出了正確方向的帖子。謝謝。 – 2016-07-22 12:18:30