定义EF中自引用List属性的列名

本文关键字:属性 List EF 自引用 定义 | 更新日期: 2023-09-27 17:53:50

我正在定义一个基于编目权限条目的类,它有许多自引用的子条目,如下所示:

public class Authority
{
    public long ID { get; set; }
    public string Term { get; set; }
    public string Language { get; set; }
    public bool PreferredTerm  { get; set; }
    public TermStatus TermStatus { get; set; }
    public Authority Use { get; set; }
    public List<Authority> UsedFor { get; set; }
    public List<Authority> Equivalent { get; set; }
    public List<Authority> Broader { get; set; }
    public List<Authority> Narrower { get; set; }
}

当在底层SQL数据库的Authority表中创建列时,每个List属性的列名是Authority_ID, Authority_ID1, Authority_ID2和Authority_ID3。

我宁愿列名是'UsedFor', 'Equivalent', ' broad '和' narrow '。我试过使用[列("名称")]属性,但它不起作用。我如何在"代码优先"中做到这一点?

定义EF中自引用List属性的列名

试试这个。我不确定外键的定义是否必须在POCO类中(您可以尝试省略它们)。

public class Authority
{
    [Key()]
    public long ID { get; set; }
    public string Term { get; set; }
    public string Language { get; set; }
    public bool PreferredTerm  { get; set; }
    public TermStatus TermStatus { get; set; }
    public Authority Use { get; set; }
    [Required]
    public long Authority_ID { get; set; }
    [Required]
    public long Authority_ID1 { get; set; }
    [Required]
    public long Authority_ID2 { get; set; }
    [Required]
    public long Authority_ID3 { get; set; }
    [ForeignKey("Authority_ID")]
    public ICollection<Authority> UsedFor { get; set; }
    [ForeignKey("Authority_ID1")]
    public ICollection<Authority> Equivalent { get; set; }
    [ForeignKey("Authority_ID2")]
    public ICollection<Authority> Broader { get; set; }
    [ForeignKey("Authority_ID3")]
    public ICollection<Authority> Narrower { get; set; }
}

您可以使用[InverseProperty("name")]为您的列表。之后,您的列名将是"UsedFor_ID","Equilavent_ID"等在数据库中(不完全对应您的问题,对不起!)。

public class Authority
{
    [InverseProperty("UsedFor")]    
    public List<Authority> UsedFor { get; set; }
    [InverseProperty("Equivalent")]  
    public List<Authority> Equivalent { get; set; }    
}

详情见:https://msdn.microsoft.com/en-us/data/gg193958http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx

谢谢你的建议。有效的方法是使用[ForeignKey]作为链接,使用[Column]来重命名列,即

    [Column("Use")]
    public long? UseID { get; set; }
    [ForeignKey("UseID")]
    public List<Authority> Use { get; set; }

然而,我在定义中也犯了一个严重的错误,因为即使我将列定义为List,上面的代码也以1到0/1键结束。我真正需要做的是添加一个子表来接受多个值。

我的最终代码看起来像这样,并且底层列名是可读的,而不是Authority_ID, Authority_ID1, Authority_ID2和Authority_ID3:

public class Authority
{
    public long ID { get; set; }
    public string Term { get; set; }
    public string Language { get; set; }
    public bool PreferredTerm  { get; set; }
    public TermStatus TermStatus { get; set; }
    //Establish 1-to-0/1 self-referencing key
    [Column("Use")]
    public long? UseID { get; set; }
    [ForeignKey("UseID")]
    public List<Authority> Use { get; set; }
    //Establis 1-many foreign keys
    [ForeignKey("UsedFor")]
    public List<AuthorityList> UsedFor { get; set; }
    [ForeignKey("Equivalent")]
    public List<AuthorityList> Equivalent { get; set; }
    [ForeignKey("Broader")]
    public List<AuthorityList> Broader { get; set; }
    [ForeignKey("Narrower")]
    public List<AuthorityList> Narrower { get; set; }
}
public class AuthorityList
{
    public long ID { get; set; }
    public long AuthorityID { get; set; }
    public long? UsedFor { get; set; }
    public long? Equivalent { get; set; }
    public long? Broader { get; set; }
    public long? Narrower { get; set; }
}

为了防止级联删除,我还在我的数据库上下文中添加了以下内容(影响整个DB而不仅仅是这些表):

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

更新答案:

使用上面的给了我想要的底层表结构,但不是我需要的功能,因为EF决定在该配置下它将映射1-1关系而不是1-M。答案在于理解EntityFramework如何管理自引用的多对多关系。即使这样,也可以通过多种方式配置,这取决于您是只想要两个1m关系还是更多关系。我要六个

最后,这个配置为我提供了我想要的功能,代价是数据库结构不太理想。

public class Tag
{
    public int ID { get; set; }
    public string Term { get; set; }
    public virtual ICollection<Tag> Broader { get; set; }
    public virtual ICollection<Tag> Narrower { get; set; }
    public virtual ICollection<Tag> Equivalent { get; set; }
    public virtual ICollection<Tag> Related { get; set; }
    public virtual ICollection<Tag> Use { get; set; }
    public virtual ICollection<Tag> Usefor { get; set; }
    public Tag()
    {
        Broader = new HashSet<Tag>();
        Narrower = new HashSet<Tag>();
        Equivalent = new HashSet<Tag>();
        Related = new HashSet<Tag>();
        Use = new HashSet<Tag>();
        Usefor = new HashSet<Tag>();
    }
}

我还需要将以下条目添加到数据库上下文的'OnModelCreating'过程中:

    modelBuilder.Entity<Tag>()
        .HasMany(x => x.Broader)
        .WithMany()
        .Map(x => x.MapLeftKey("TagID").MapRightKey("BroaderID").ToTable("TagBroader"));
    modelBuilder.Entity<Tag>()
        .HasMany(x => x.Equivalent)
        .WithMany()
        .Map(x => x.MapLeftKey("TagID").MapRightKey("EquivalentID").ToTable("TagEquivalent"));
    modelBuilder.Entity<Tag>()
        .HasMany(x => x.Narrower)
        .WithMany()
        .Map(x => x.MapLeftKey("TagID").MapRightKey("NarrowerID").ToTable("TagNarrower"));
    modelBuilder.Entity<Tag>()
            .HasMany(x => x.Related)
            .WithMany()
            .Map(x => x.MapLeftKey("TagID").MapRightKey("RelatedID").ToTable("TagRelated"));
    modelBuilder.Entity<Tag>()
        .HasMany(x => x.Use)
        .WithMany()
        .Map(x => x.MapLeftKey("TagID").MapRightKey("UsedID").ToTable("TagUse"));
    modelBuilder.Entity<Tag>()
        .HasMany(x => x.Usedfor)
        .WithMany()
        .Map(x => x.MapLeftKey("TagID").MapRightKey("UsedforID").ToTable("TagUsedfor"));
为了进行测试,我使用了以下命令:
        //Broader/Narrower example
        var music = new Tag{ Term = "Music"};
        var jazz = new Tag{ Term = "Jazz Music" };
        var classical = new Tag{ Term = "Classical Music" };
        music.Narrower.Add(jazz);
        music.Narrower.Add(classical);
        jazz.Broader.Add(music);
        classical.Broader.Add(music);
        //Equivalent example
        var zucchini = new Tag{ Term = "Zucchini" };
        var courgette = new Tag{ Term = "Courgette" };
        zucchini.Equivalent.Add(courgette);
        courgette.Equivalent.Add(zucchini);
        context.Tags.Add(music);
        context.Tags.Add(jazz);
        context.Tags.Add(classical);
        context.Tags.Add(zucchini);
        context.Tags.Add(courgette);
        context.SaveChanges();
相关文章: