这是我的第一个问题,我希望不是一个愚蠢的问题。
我这里有以下实体
客户 公司 电话
public class Customers
{
public Customers()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Phones> Phones { get; set; }
}
public class Phones
{
public Guid Id { get; set; }
public string Number { get; set; }
public string Extension { get; set; }
}
public class Companies
{
public Companies()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<Phones> Phones { get; set; }
}
我想用流利的api创建手机之间的一对多关系,与公司和手机相同。
答案 0 :(得分:6)
我不确定您是否需要以下内容:
modelBuilder.Entity<Customers>()
.HasMany(c => c.Phones)
.WithOptional()
.Map(m => m.MapKey("CustomerPhoneId"));
modelBuilder.Entity<Companies>()
.HasMany(c => c.Phones)
.WithOptional()
.Map(m => m.MapKey("CompanyPhoneId"));
使用MapKey
是可选的。它只是为外键列提供了您想要的名称。如果省略此EF,将创建一个标准名称(带下划线的内容:..._Id
)。
实际上整个映射是可选的,因为映射约定只会创建相同的关系,而根本没有任何Fluent API映射。
Phones
表将有两个可以为空的外键CustomerPhoneId
和CompanyPhoneId
分别引用Customers
表和Companies
表。
修改强>
另一个只需要Phone
表中一个外键用于多个不同实体的替代方法就是继承映射:
public abstract class OrganizationsWithPhone
{
public OrganizationsWithPhone()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public ICollection<Phones> Phones { get; set; }
}
public class Customers : OrganizationsWithPhone
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Companies : OrganizationsWithPhone
{
public string Name { get; set; }
}
public class Phones
{
public Guid Id { get; set; }
public string Number { get; set; }
public string Extension { get; set; }
}
映射:
modelBuilder.Entity<OrganizationsWithPhone>()
.HasMany(o => o.Phones)
.WithOptional() // or .WithRequired()
.Map(m => m.MapKey("OrganizationsWithPhoneId"));
modelBuilder.Entity<OrganizationsWithPhone>()
.ToTable("OrganizationsWithPhone");
modelBuilder.Entity<Customers>()
.ToTable("Customers");
modelBuilder.Entity<Companies>()
.ToTable("Companies");
现在Phones
和基表OrganizationsWithPhone
之间只有一个外键关系,但由于继承映射,基表和表之间存在额外的一对一关系派生实体Customers
和Companies
。基本上,必要关系的数量保持不变(或者在此模型中甚至还有一个)。
在此模型中,客户和公司不能共享相同的电话号码,因为Phones
表中的一行指的是OrganizationsWithPhone
,可以是客户或公司,但不能同时是同一时间。
基表OrganizationsWithPhone
只有一列Id
。如果您在所有派生实体中有更多共同属性,则可以将它们移动到基本权限中。
答案 1 :(得分:1)
你需要的是我所谓的关联表,你需要让EF创建一个单独的表来保存关系细节。我不知道EF是否能够做到这一点。但是如果您可以更改对象模型,那么一种解决方案可能是为这些表指定特定类型。
public class CustomerPhone
{
public int Id { get; set; }
public Customers Customer { get; set; }
public Phones Phone { get; set; }
}
public class CompanyPhone
{
public int Id { get; set; }
public Companies Company { get; set; }
public Phones Phone { get; set; }
}
现在这些类可以保持这种关系,所以现在你可以用它们替换Phone:
public class Customers
{
public Customers()
{
Phones = new List<CustomerPhone>();
}
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<CustomerPhone> Phones { get; set; }
}
public class Companies
{
public Companies()
{
Phones = new List<CompanyPhone>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<CompanyPhone> Phones { get; set; }
}
通过这种方式,您可以为您的关系添加更多详细信息,例如创建日期等。
答案 2 :(得分:0)
参见本教程 - 教师与部门之间,课程与入学之间以及学生与入学之间有一对多的关系,您可以将其用作模型: