[英]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
具有TypeA
或TypeB
外键。 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
进行分组时完成此操作,但是TypeA
和TypeB
具有许多属性,我想避免在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). 我这样做是出于理智,以防万一TypeA
和TypeB
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.