我想跟随this blog解释如何配置一对一关系。它的想法是,一个实体获得另一个类型的属性,而另一个获得前者类型的属性以及一个ID,以创建外键。
但是,我的问题是,我想像这样制动两个不同类的接触部分。 SomeThing 类已经被重构,并且可以与 Address 类一起很好地工作。但是,我不确定如何处理 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 的地址,但是将其分解是没有任何意义的。我考虑过在下面添加两个字段,但由于数据库设计不良而拒绝了这个想法。
public class Address
{
...
public Guid SomeThingElseId { get; set; }
public SomeThingElse SomeThingElse { get; set; }
}
最好是一个用于继承的教科书案例,引入了一个基类 Contactable 并完全跳过了 Address 。但是我从前曾记得,继承和EF混合得不好,在这种情况下会有很多麻烦和麻烦。
是否有可靠的最佳做法?当我用Google搜索时,没有发现任何值得信赖的东西。
答案 0 :(得分:3)
从评论中的讨论中,我将进入详细答案:
您可以使用 EF Core 新引入的Owned Entity类型的功能,其中Address
是Owned Entity
和Something
的{{1}}类型SomethingElse
和Something
是所有者,如下所示:
SomethingElse
按照惯例,EF核心将命名以下的图案为拥有实体类型的属性的数据库中的列的 Navigation_OwnedEntityProperty 。因此,modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address);
modelBuilder.Entity<SomeThingElse>().OwnsOne(st => st.Address);
特性将出现在Address
和Something
表的名字 'Address_Street' 和 'ADDRESS_CITY'。
现在,如果您不希望拥有实体类型的列名类似于 Navigation_OwnedEntityProperty ,则可以按以下方式提供自定义列名:
SomethingElse
此外,可以将拥有的类型与所有者存储在单独的表中。为了覆盖将拥有的类型映射到与所有者相同的表的约定,您可以简单地调用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
在查询所有者时,默认情况下将包括拥有的类型。即使拥有的类型存储在单独的表中,也不必使用Include方法。
其中一些限制对于拥有实体类型的工作方式至关重要,但另一些限制则是我们可以在将来的版本中删除的限制:
受设计限制:
modelBuilder.Entity<SomeThing>().OwnsOne(st => st.Address,
a =>
{
a.ToTable("SomeThingAddress");
});
modelBuilder.Entity<SomeThingElse>().OwnsOne(ste => ste.Address,
a =>
{
a.ToTable("SomeThingElseAddress");
});
DbSet<T>
上以拥有的类型呼叫Entity<T>()