Entity Framework 有条件的一对多
Entity Framework one to many with condition
我有一份工作class
[Table("Jobs")]
public class Job
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("fID")]
public int ID { get; set; }
public virtual ICollection<Note> Notes { get; set; }
}
笔记 class 看起来像这样:
[Table("Note")]
public class Note
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("fID")]
public int ID{get; set;}
[Column("fld_int_NoteTypeID")]
public int NoteTypeID { get; set; }
}
每当我从这样的工作中请求注释时:
var job= context.Jobs.Include(x => x.Notes).FirstOrDefault(x => x.ID == jobId);
我希望查询隐式添加 Where NoteTypeId == 8
.
是否可以通过某种方式添加此子句,还是每次都必须明确添加?
解决方法是什么?添加 NotMapped 属性 过滤 Notes 集合:
[Table("Jobs")]
public class Job
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("fID")]
public int ID { get; set; }
public virtual ICollection<Note> Notes { get; set; }
[NotMapped]
public ICollection<Note> FilteredNotes
{
get
{
return Notes.Where(m => m.NoteTypeId == 8);
}
}
}
但是这个设计的问题是,当你 select 像 var job = context.Jobs.Include(x => x.Notes).FirstOrDefault(x => x.ID == jobId);
这样的工作时,你将所有的笔记加载到内存中,然后你可以像 job.FilteredNotes
这样从内存中访问过滤的笔记.但是当使用 LazyLoading
时它有优势。
var job = context.Jobs.FirstOrDefault(x => x.ID == jobId);
var notes = job.FilteredNotes.ToList();
更新
您也可以尝试 Table-per-Hierarchy (TPH) mappimg。您必须创建一个抽象 class 和派生 classes:
public abstract class Note
{
public int Id { get; set; }
public int NoteTypeId { get; set; }
}
public class JobNote : Note
{
}
public class OtherNote : Note
{
}
然后覆盖OnModelCreating
方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Note>()
.Map<JobNote>(m => m.Requires("NoteTypeId").HasValue(8))
.Map<OtherNote>(m => m.Requires("NoteTypeId").HasValue(3)); // For example
}
请注意,我对 TPH 的了解还不够。我只是想展示一些提示。请进一步阅读 TPH。
我有一份工作class
[Table("Jobs")]
public class Job
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("fID")]
public int ID { get; set; }
public virtual ICollection<Note> Notes { get; set; }
}
笔记 class 看起来像这样:
[Table("Note")]
public class Note
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("fID")]
public int ID{get; set;}
[Column("fld_int_NoteTypeID")]
public int NoteTypeID { get; set; }
}
每当我从这样的工作中请求注释时:
var job= context.Jobs.Include(x => x.Notes).FirstOrDefault(x => x.ID == jobId);
我希望查询隐式添加 Where NoteTypeId == 8
.
是否可以通过某种方式添加此子句,还是每次都必须明确添加?
解决方法是什么?添加 NotMapped 属性 过滤 Notes 集合:
[Table("Jobs")]
public class Job
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("fID")]
public int ID { get; set; }
public virtual ICollection<Note> Notes { get; set; }
[NotMapped]
public ICollection<Note> FilteredNotes
{
get
{
return Notes.Where(m => m.NoteTypeId == 8);
}
}
}
但是这个设计的问题是,当你 select 像 var job = context.Jobs.Include(x => x.Notes).FirstOrDefault(x => x.ID == jobId);
这样的工作时,你将所有的笔记加载到内存中,然后你可以像 job.FilteredNotes
这样从内存中访问过滤的笔记.但是当使用 LazyLoading
时它有优势。
var job = context.Jobs.FirstOrDefault(x => x.ID == jobId);
var notes = job.FilteredNotes.ToList();
更新
您也可以尝试 Table-per-Hierarchy (TPH) mappimg。您必须创建一个抽象 class 和派生 classes:
public abstract class Note
{
public int Id { get; set; }
public int NoteTypeId { get; set; }
}
public class JobNote : Note
{
}
public class OtherNote : Note
{
}
然后覆盖OnModelCreating
方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Note>()
.Map<JobNote>(m => m.Requires("NoteTypeId").HasValue(8))
.Map<OtherNote>(m => m.Requires("NoteTypeId").HasValue(3)); // For example
}
请注意,我对 TPH 的了解还不够。我只是想展示一些提示。请进一步阅读 TPH。