C# 声明的导航属性Project.Models.Customer.SubCustomers的类型与指定导航的结果不兼容

C# 声明的导航属性Project.Models.Customer.SubCustomers的类型与指定导航的结果不兼容,c#,ef-code-first,entity-framework-6,entity-framework-migrations,ef-fluent-api,C#,Ef Code First,Entity Framework 6,Entity Framework Migrations,Ef Fluent Api,我看过类似错误的答案,但似乎找不到我的特定错误的答案 我正在运行迁移,当种子方法运行时会发生错误迁移工作正常 声明的导航属性Project.Models.Customer.SubCustomers的类型与指定导航的结果不兼容 这用于循环引用,即客户可以有0..*子客户和0..1父客户 客户模式: public class Customer : Entity { public int CustomerId { get; set;} public string Name { get;

我看过类似错误的答案,但似乎找不到我的特定错误的答案

我正在运行迁移,当种子方法运行时会发生错误迁移工作正常

声明的导航属性Project.Models.Customer.SubCustomers的类型与指定导航的结果不兼容

这用于循环引用,即客户可以有0..*子客户和0..1父客户

客户模式:

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
}
从上下文fluent 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();

如果有人能找出错误的原因,我将不胜感激。非常感谢

经过一番阅读和反复尝试,我终于明白了这一点。我感到困惑,因为这是自我参照,遗漏了一个关键因素

通常,在两个不同对象之间创建一对多关系时,您会有如下情况:

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;}
}
以及fluent 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);
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();

感谢您发布此问题和答案。今天早上,我们已经为这个问题挣扎了几个小时,这篇文章为我们指明了正确的方向。非常感谢。
// 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();