我有两个班级
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
包含多个属性,我希望避免在new
个关键字中写入select
语句分配所有属性。
编辑:
我对现在拥有的东西非常满意。我这样做是为了理智,以防TypeA
和TypeB
id属性相同(99.9999999它不会)。
答案 0 :(得分:0)
如果您已正确设置实体映射,则无需在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)。