![](/img/trans.png)
[英]How to use multiple tables with the same foreign key with Entity Framework
[英]Same column foreign key referencing multiple tables in Entity Framework
我有两个课
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
具有TypeA
或TypeB
外键。 并且有一个属性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)
我想可以在对查询中的Comment
进行分组时完成此操作,但是TypeA
和TypeB
具有许多属性,我想避免在select
语句中编写new
关键字来分配所有属性。
编辑:
我对自己现在拥有的一切感到非常满意。 我这样做是出于理智,以防万一TypeA
和TypeB
id属性是相同的(99.9999999不会)。
如果正确设置了实体映射,则无需在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)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.