具有自定义get方法的EF虚拟集合

时间:2016-06-24 17:28:37

标签: c# asp.net asp.net-mvc entity-framework

在EF中是否可以拥有一个虚拟集合,该集合对其提取的数据进行自定义查询?

例如,如果我有一个类person.cs并且我在该类中有一个属性:public ICollection<job> jobs,但我希望该属性由我编写的自定义查询定义,例如, _context.jobs.where(j => j.backup_person_id == id).select(j);而不是默认只在person_id表上查找jobs

这可能吗?如果是这样,它是如何实现的?

[编辑]

更具体地说:我们假设jobs表格有两列managermain_lead。然后,我希望我的person.cs类具有属性:ICollection<job> managerJobs,其中包含<job>字段与manager字段匹配person_code字段的所有person条目{1}}和ICollection<job> main_leadJobs,其中包含<job>字段与main_lead的{​​{1}}字段匹配的所有person_code条目,

在我看来,这似乎很简单:person = ICollection<job> managerJobsselect * from tbl_jobs where manager = person_code = ICollection<job> main_leadJobs

我希望这比我上面的内容更有意义

1 个答案:

答案 0 :(得分:0)

没有。这不可能。但是,更一般地说,您想要实现的目标是可能的,只是以不同的方式。请参阅MSDN文章:https://msdn.microsoft.com/en-us/data/jj574232.aspx#explicitFilter

如果您处理特定的person,而不是通常包括jobs,则可以执行以下操作:

var person = _context.People.Find(personId);
_context.Entry(person)
    .Collection(b => b.jobs) 
    .Query() 
    .Where(j => j.backup_person_id == backupId) 
    .Load();

然后,当您访问person.jobs集合时,它只会是那些已过滤的项目。这意味着您有两个查询,而如果您只是通过Include手动加载所有作业,则可以在一个查询中完成。

如果你有多个人正在使用,那么这个显式加载必须多次完成,这意味着每个人的查询(N + 1)。在这种情况下,您最好不要单独查询每个实体:

var people = db.People.Where(...).ToList();
var jobs = db.Jobs.Where(m => people.Select(m => m.Id).Contains(m.person_id) && m.backup_person_id == backupId).ToList();

换句话说,您只查询属于特定选定人员的作业,然后根据您的标准进一步限制,在这种情况下,该标准是备份人员的ID。然后,当您在人群中进行迭代时,您可以将内存中的jobs过滤为仅适用于上下文中当前人员的作业。