【问题标题】:Same column foreign key referencing multiple tables in Entity Framework实体框架中引用多个表的同一列外键
【发布时间】:2017-11-23 01:19:11
【问题描述】:

我有两节课

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

然后是

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 具有 TypeATypeB 的外键。还有一个属性Type,它告诉我们引用了哪个外键。

现在我就去做

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

但是是否可以限制Include 语句或编写一个查询来检查Type 属性以获取适当的外键引用,例如

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

我想这可以在查询中对Comments 进行分组时完成,但是TypeATypeB 有许多属性,我想避免在select 语句中写new 关键字来分配所有属性.

编辑:

我对我现在所拥有的非常满意。我这样做是为了理智,以防TypeATypeB id 属性相同(99.9999999 不会)。

【问题讨论】:

  • 请给您的问题一个有意义的标题。并尝试通过“过滤包含”找到一些帖子。不支持。
  • 是写一个选择的存储过程,并使用EF调用它。但 EF 本身没有?
  • 出于好奇,为什么会有两种看起来一模一样的类型?拥有一个带有 Type 字段的类不是更有意义吗?我非常希望您的代码只是一个不完整的示例。
  • 不,这只是非常小的样本,TypeA 和 TypeB 在结构和用途上都是不同的类。他们恰好有相同的班级Comment。为CommentForTypeACommentForTypeB 设置两个表是没有意义的。
  • @MantasČekanauskas 嘿!你是怎么解决这个问题的。我在这里遇到了类似的问题,我想我把整个映射弄错了。你能帮我看看吗? stackoverflow.com/questions/56584027/…

标签: c# entity-framework foreign-keys


【解决方案1】:

如果您已正确设置实体映射,则无需在 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());
    }
}

唯一的缺点是会涉及到额外的链接表(TypeAComment,TypeBComment)。

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 2016-05-07
    • 2019-02-23
    • 1970-01-01
    相关资源
    最近更新 更多