我想跟着this blog解释如何配置一个一对一的关系。它的想法是,一个实体获取其他的类型的属性,而其他人得到前者的类型的属性加一个ID给它创建一个外键。
我的问题是,虽然,我想刹车了两种不同类型的,像这样的接触部分。类的东西已经被重构,并与类地址效果很好。但是,我不知道该如何处理类SomeThingElse。
public class SomeThing
{
public Guid Id { get; set; }
//public string Street { get; set; }
//public string City { get; set; }
public Address Address { get; set; }
}
public class Address
{
public Guid Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public Guid SomeThingId { get; set; }
public SomeThing SomeThing { get; set; }
}
public class SomeThingElse
{
public Guid Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
//public Address Address { get; set; }
}
我试着加入一个专门类管理SomeThingElse的地址,但随后,它是没有意义的,打破它。我认为加入下面的两个领域,但拒绝了这一提议为DB设计为差。
public class Address
{
...
public Guid SomeThingElseId { get; set; }
public SomeThingElse SomeThingElse { get; set; }
}
优选地,这是一个学校的书的情况下为继承引入基类接触并完全跳过地址。但我从继承之前调用和EF不拌匀,并且有很多oopsies和陷阱在这种情况下可以预期的。
是否有可靠的最佳实践做这件事?我没有发现任何东西,当我用Google搜索是觉得有足够可信。
由于从意见的讨论中,我进入一个细节回答:
您可以使用EF核心新引进Owned Entity类型的功能,使Address
是Owned Entity
和Something
的SomethingElse
类型,而Something
和SomethingElse
是业主如下:
modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address);
modelBuilder.Entity<SomeThingElse>().OwnsOne(st => st.Address);
按照惯例,EF核心将是继模式Navigation_OwnedEntityProperty名称为拥有实体类型的属性的数据库列。因此,Address
属性将出现在Something
和SomethingElse
表的名字“Address_Street”和“ADDRESS_CITY”。
现在,如果你不想拥有的实体类型列名要像Navigation_OwnedEntityProperty那么你可以给你的自定义列名如下:
modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address,
a =>
{
a.Property(p => p.Street).HasColumnName("Street");
a.Property(p => p.City).HasColumnName("City");
});
modelBuilder.Entity<SomeThingElse>().OwnsOne(ste => ste.Address,
a =>
{
a.Property(p => p.Street).HasColumnName("Street");
a.Property(p => p.City).HasColumnName("City");
});
而且资类型可存储在从所有者一个单独的表。为了重写一个拥有类型映射到同一个表所有者的约定,你可以简单地调用ToTable
并提供不同的表名,如下所示:
modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address,
a =>
{
a.ToTable("SomeThingAddress");
});
modelBuilder.Entity<SomeThingElse>().OwnsOne(ste => ste.Address,
a =>
{
a.ToTable("SomeThingElseAddress");
});
当查询所有者所拥有的类型默认情况下将包括在内。这是没有必要使用include方法,即使所有的类型都存储在一个单独的表。
这些限制是如何拥有实体类型工作的基础,但有些则限制,我们也许能够在未来的版本中删除:
通过设计限制:
DbSet<T>
Entity<T>()
一家拥有呼叫类型ModelBuilder