我想有条件地加载一个实体和它的子项(我只想在child.IsActive == true时加载子项。)我该如何执行以下操作?
var parent =
from p in db.tblParents.Include("tblChildren") <-- where tblChildren.IsActive == true
where p.PrimaryKey == 1
select p;
注意:我不想返回匿名类型。
感谢。
答案 0 :(得分:9)
这样做的一种方法是:
var parent = from p in db.tblParents where p.PrimaryKey == 1
select new {
Parent = p,
Children = p.tblChildren.Where(c => c.IsActive == true)
}.ToList();
但是,您可能不喜欢返回匿名类型的想法,然后我建议以这种方式编写代码:
var parent = (from p in db.tblParents where p.PrimaryKey == 1).Single();
var childrens = ctx.Contacts.Where(c => c.ParentID == 1 && c.IsActive == true);
foreach (var child in childrens) {
parent.tblChildren.Add(child);
}
答案 1 :(得分:2)
为了能够应用过滤器,更好的选择是使用明确加载以及 Query()而不是 Eager 加载:
sharedpreferences
Query方法提供对实体框架在加载相关实体时将使用的基础查询的访问。此外,您还需要关闭延迟加载以获取导航属性(删除虚拟关键字),否则将通过延迟加载自动加载集合,忽略您的过滤器。
答案 2 :(得分:1)
实体框架6引入了拦截http://entityframework.codeplex.com/wikipage?title=Interception,可用于调整SQL以过滤子项。
在执行查询之前,添加一个拦截器,并在它不相关时删除:
var interceptor = new ActiveTagsInterceptor();
DbInterception.Add(interceptor);
documents = context.Documents
.AsQueryable()
.Include(d => d.Tags)
DbInterception.Remove(interceptor);
示例拦截器添加&#34; [Active] = 1和&#34;加载标签时:
public class ActiveTagsInterceptor : IDbCommandInterceptor
{
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
// [Tag] AS [Extent6] ON => [Tag] AS [Extent6] ON [Extent6].[Active] = 1 And
const string pattern = "\\[Tag\\]\\sAS\\s\\[([\\w]+)\\]\\sON";
const string replacement = "$& [$1].[Active] = 1 And ";
command.CommandText = Regex.Replace(command.CommandText, pattern, replacement);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
}
}