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