Entity Framework 中相同 class 的多个列表
Multiple lists of same class in Entity Framework
我试图首先在 Entity Framework 代码中创建与相同类型有关系的公司的数据模型。我想创建单向关系,因此当一家公司将另一家公司添加为客户时,另一家公司不会自动将该公司作为供应商。
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" 的连接 table。
公司公司
| Company_Id | Company_Id1 |
|------------|-------------|
| 1234 | 1234 |
我想创建两个 table 来连接这些值,如下所示:
公司客户
| Company_Id | Customer_Id |
|------------|-------------|
| 1234 | 1234 |
公司供应商
| 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");
});
Error Number:-2,State:0,Class:11
Execution Timeout Expired.
The timeout period elapsed prior to completion of the operation or the server is not responding.
当我同时尝试使用 CompanyCustomer 和 CompanySupplier 时,出现了另一个错误
Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong.
我还尝试为该关系创建一个新对象,并让 Company 对象持有一个 CompanyCustomers 列表,但是当我用它更新数据库时,我得到了一个包含三列的连接-table。
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; }
}
公司客户
| CompanyId | CustomerID | Company_Id |
|-----------|------------|------------|
| 1234 | 1234 | 1234 |
我不明白如何在同一实体之间建立多种关系类型。我可以在 fluent 的帮助下做到这一点 api 还是我必须重新设计我的模型?
您可以只使用属性来做到这一点。您的问题是您在错误的 属性 上使用了 [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; }
流畅配置
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 和流畅的配置, 更新数据库以清除以前的混乱并重试。
我试图首先在 Entity Framework 代码中创建与相同类型有关系的公司的数据模型。我想创建单向关系,因此当一家公司将另一家公司添加为客户时,另一家公司不会自动将该公司作为供应商。
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" 的连接 table。
公司公司
| Company_Id | Company_Id1 |
|------------|-------------|
| 1234 | 1234 |
我想创建两个 table 来连接这些值,如下所示:
公司客户
| Company_Id | Customer_Id |
|------------|-------------|
| 1234 | 1234 |
公司供应商
| 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");
});
Error Number:-2,State:0,Class:11 Execution Timeout Expired.
The timeout period elapsed prior to completion of the operation or the server is not responding.
当我同时尝试使用 CompanyCustomer 和 CompanySupplier 时,出现了另一个错误
Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong.
我还尝试为该关系创建一个新对象,并让 Company 对象持有一个 CompanyCustomers 列表,但是当我用它更新数据库时,我得到了一个包含三列的连接-table。
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; }
}
公司客户
| CompanyId | CustomerID | Company_Id |
|-----------|------------|------------|
| 1234 | 1234 | 1234 |
我不明白如何在同一实体之间建立多种关系类型。我可以在 fluent 的帮助下做到这一点 api 还是我必须重新设计我的模型?
您可以只使用属性来做到这一点。您的问题是您在错误的 属性 上使用了 [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; }
流畅配置
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 和流畅的配置, 更新数据库以清除以前的混乱并重试。