gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 20:46:27 25 4
gpt4 key购买 nike

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

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

The declared type of navigation property Project.Models.Customer.SubCustomers is not compatible with the result of the specified navigation.

这是为了循环引用,即一个客户可以有 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
}

来自上下文流畅的 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);

from seed方法:(在数据库中创建客户,子客户不起作用)

// 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;}
}

然后在上下文中(流畅的 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;设置;在这种情况下。

因此,要创建一个自引用的 Foo,您需要将关系的所有三个元素(在上面的示例中拆分为两个对象)放在 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();

关于c# - 导航属性 Project.Models.Customer.SubCustomers 的声明类型与指定导航的结果不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26934962/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com