我们已经决定将所有枚举合并到一个RefValue表中,我至少对此没有任何疑问,但是我似乎无法让Entity发挥作用。

我认为,一旦您查看了架构,这应该很有意义,但是要点是,当涉及枚举时,Person对象将具有2个字段(例如,gender,relationshipStatus,nameSuffix等)。一个字段将存储值(例如“ female”),而另一个字段将存储该RefValue的ID(例如,一些guid,该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);
    }


有没有什么方法可以创建这种一对多(或实际上是多对一)的关系,而又无需级联问题或(尤其是)实体在非依赖表上创建阴影属性?

最佳答案

让我们采用原始的实体模型:

[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; }
}


使用Fluent 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将创建其他关系。

10-05 22:36