简体   繁体   English

同一列外键引用实体框架中的多个表

[英]Same column foreign key referencing multiple tables in Entity Framework

I have two class 我有两个课

public class TypeA
{
    public Guid Id { get; set; }
    public List<Comment> Comments { get; set; }
}
public class TypeB
{
    public Guid Id { get; set; }
    public List<Comment> Comments { get; set; }
}

And then there is 然后有

public class Comment
{
    public Guid Id { get; set; }
    public Guid ParentId { get; set; } //foreign key either to TypeA or TypeB
    public int Type { get; set; } //shows which class is referenced by foreign key ParentId
}

Comment have foreign key either to TypeA or to TypeB . Comment具有TypeATypeB外键。 And there is property Type which tells which foreign key is being referenced . 并且有一个属性Type ,它告诉您正在引用哪个外键。

Now I just do 现在我要做

_context.Set<TypeA>().Include(x => x.Comments).First(x => x.Id == Id)

But is it possible to limit Include statement or write a query which would check Type property for appropriate foreign key reference, something like 但是可以限制Include语句或编写查询来检查Type属性以获取适当的外键引用,例如

_context.Set<TypeA>().Include(x => x.Comments.Where(c=>c.Type == 1)).First(x => x.Id == Id)

I imagine it could be done while grouping Comment s in query, but TypeA and TypeB has number of properties and I would like to avoid writing new keyword in select statement to assign all properties. 我想可以在对查询中的Comment进行分组时完成此操作,但是TypeATypeB具有许多属性,我想避免在select语句中编写new关键字来分配所有属性。

EDIT: 编辑:

I' pretty much happy with what I have now. 我对自己现在拥有的一切感到非常满意。 I am doing this for sanity, just in case TypeA and TypeB id property would be the same (99.9999999 it won't). 我这样做是出于理智,以防万一TypeATypeB id属性是相同的(99.9999999不会)。

You don't need to filter something in the Include statement if you have set up your entity mappings properly. 如果正确设置了实体映射,则无需在Include语句中过滤某些内容。

public class TypeA
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public virtual ICollection<Comment> Comments { get; set; } = new List<Comment>();
    public Comment AddComment(string text)
    {
        var comment = new Comment { Id = Guid.NewGuid(), ParentId = Id, Type = Types.TypeA, Text = text };
        Comments.Add(comment);
        return comment;
    }
}

public class TypeB
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public virtual ICollection<Comment> Comments { get; set; } = new List<Comment>();
    public Comment AddComment(string text)
    {
        var comment = new Comment { Id = Guid.NewGuid(), ParentId = Id, Type = Types.TypeB, Text = text };
        Comments.Add(comment);
        return comment;
    }
}

public enum Types
{
    TypeA = 0,
    TypeB = 1
}

public class Comment
{
    public Guid Id { get; set; }
    public Guid ParentId { get; set; }
    public Types Type { get; set; }
    public string Text { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<TypeA> TypeAs { get; set; }
    public DbSet<TypeB> TypeBs { get; set; }

    public MyContext() : base("Name=MyContext") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<TypeA>()
            .HasKey(e => e.Id)
            .HasMany(e => e.Comments).WithMany();

        modelBuilder.Entity<TypeB>()
            .HasKey(e => e.Id)
            .HasMany(e => e.Comments).WithMany();
    }
}
internal sealed class Configuration : DbMigrationsConfiguration<MyContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }
}

void Main()
{   
    // helper code to use migrations, just for demo purposes
    var migrator = new DbMigrator(new Configuration());
    migrator.Update();
    //

    var db = new MyContext();
    var a = new TypeA { Id = Guid.NewGuid() };
    db.TypeAs.Add(a);

    var b = new TypeB { Id = Guid.NewGuid() };
    db.TypeBs.Add(b);

    db.SaveChanges();

    a.AddComment("A1 ");
    a.AddComment("A2");

    b.AddComment("B1");
    b.AddComment("B2");
    b.AddComment("B3");

    db.SaveChanges();

    var dba = db.TypeAs.Include(x => x.Comments).First(e => e.Id == a.Id);
    foreach (var c in dba.Comments)
    {
        Console.WriteLine("{0} {1} {2} {3}", c.Text, c.Id, c.ParentId, c.Type.ToString());
    }
}

The only drawback is that there will be additional linking tables involved (TypeAComment, TypeBComment). 唯一的缺点是将涉及其他链接表(TypeAComment,TypeBComment)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Entity Framework中使用具有相同外键的多个表 - How to use multiple tables with the same foreign key with Entity Framework 在同一列上具有多个外键的实体框架核心 - Entity Framework Core with Multiple Foreign Key On Same Column 多个表/实体的实体框架外键 - Entity Framework foreign key to multiple tables/entities 实体框架中相同类型的多个外键 - Multiple foreign key of the same type in Entity Framework 将列表插入具有外键关系实体框架的多个表中 - Insert list into multiple tables with foreign key relationship Entity Framework 实体框架可以将同一列映射到导航属性和外键吗 - Can Entity Framework map the same column to a Navigation Property and a Foreign Key 实体框架代码中相同表的多个外键优先 - Multiple Foreign Key for Same table in Entity Framework Code First 实体框架,插入了引用最后一个Id的外键,同时也是同一张表上之前的集合 - Entity framework, Foreign Key referencing last Id was inserted, and also a collection of previous ones on the same table 实体框架-多个表引用一个表 - Entity Framework - Multiple tables referencing to one table 实体框架:如何在自引用父子关系上指定外键列的名称? - Entity Framework: How to specify the name of Foreign Key column on a self-referencing Parent-Child relationship?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM