我们决定将所有枚举合并到一个RefValue表中,至少我没有遇到任何问题,但我似乎无法让Entity一起玩。
我认为一旦你看到模式就应该有意义,但它的要点是Person对象在枚举时会有2个字段(例如gender,relationshipStatus,nameSuffix等)。一个字段将存储该值(例如" female"),另一个字段将存储该RefValue的id(例如,一些guid,它将是存储/定义值的RefValue表的外键)。这样我们就不必在RefValue表上进行多次连接来查找这些属性值。
这是架构:
[Table("Person")]
public class Person : Base
{
public Guid Id {get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public RefValue GenderRef { get; set; }
public string RelationshipStatus { get; set; }
public RefValue RelationshipStatusRef { get; set; }
public string NameSuffix { get; set; }
public RefValue NameSuffixRef { get; set; }
}
[Table("RefValue")]
public class RefValue : Base
{
public Guid Id {get; set; }
public string Type { get; set; }
public string Value { get; set; }
}
在Person对象中,我真的只是将RefValue属性作为Guid作为RefValue表的外键。我开始转向使它们成为RefValue属性,因为如果我按照导航属性的概念进行操作,EFC似乎会让事情变得更容易。但问题是,它非常坚持让RefValue表上的列成为这些一对多关系的另一面。
我可以在RefValue表上添加额外的列,这样看起来更像是这样:
[Table("RefValue")]
public class RefValue : Base
{
public string Type { get; set; }
public string Value { get; set; }
public ICollection<Person> Genders { get; set; }
public ICollection<Person> RelationshipStatus { get; set; }
public ICollection<Person> NameSuffix { get; set; }
}
但无论我如何旋转我的上下文类OnModelCreating()
方法,我似乎无法让它们一起玩。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<RefValue>()
.HasMany(p => p.Genders)
.WithOne(p => p.GenderRef)
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<RefValue>()
.HasMany(p => p.RelationshipStatus)
.WithOne(p => p.RelationshipStatusRef)
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<RefValue>()
.HasMany(p => p.NameSuffix)
.WithOne(p => p.NameSuffixRef)
.OnDelete(DeleteBehavior.SetNull);
}
我也尝试过相反的方式,但我通常会得到Introducing FOREIGN KEY constraint ... on table ... may cause cycles or multiple cascade paths
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasOne(p => p.PersonTypeRef)
.WithMany()
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<Person>()
.HasOne(p => p.RelationshipStatusRef)
.WithMany()
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<Person>()
.HasOne(p => p.NameSuffixRef)
.WithMany()
.OnDelete(DeleteBehavior.SetNull);
}
有没有办法在没有级联问题的情况下创建这种一对多(或真正多对一)的关系,或者(特别是)实体在非依赖表上创建阴影属性?< / p>
答案 0 :(得分:2)
让我们采用您的原始实体模型:
[Table("Person")]
public class Person : Base
{
public Guid Id {get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public RefValue GenderRef { get; set; }
public string RelationshipStatus { get; set; }
public RefValue RelationshipStatusRef { get; set; }
public string NameSuffix { get; set; }
public RefValue NameSuffixRef { get; set; }
}
[Table("RefValue")]
public class RefValue : Base
{
public Guid Id {get; set; }
public string Type { get; set; }
public string Value { get; set; }
}
使用流畅的API配置单向(即仅在一侧具有导航属性)FK关系绝对没有问题。您唯一需要考虑的是,由于此类模型引入的多个级联路径,您无法使用删除级联选项,即您应指定DeleteBehavior.Restrict
。
话虽如此,这里是上述模型的流畅配置:
modelBuilder.Entity<Person>()
.HasOne(p => p.GenderRef)
.WithMany()
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Person>()
.HasOne(p => p.RelationshipStatusRef)
.WithMany()
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Person>()
.HasOne(p => p.NameSuffixRef)
.WithMany()
.OnDelete(DeleteBehavior.Restrict);
如果您添加了集合导航属性,请不要忘记在相应的WithMany
调用中指定它们,否则EF Core将创建其他关系。
答案 1 :(得分:1)
我们决定将所有枚举合并到RefValue表中
这让我感到难过。你如何阻止人们成为单身性别或女性的关系状态?如何使用特定外键的所有有效值填充下拉列表?您如何帮助报告作者正确加入表格?
我似乎无法让他们一起玩。
那是因为你所尝试的是对关系设计的根本违反。这只是许多困难中的第一个,应该让你重新思考这个设计。