Entity Framework 条件无效的 .Include()
Entity Framework .Include() with condition not working
场景
如果我拆分 Entity Framework linq 查询以首先评估 IQueryable
,然后再尝试包含一些属性,则 AccessGroupAccessPoints
和 AccessGroupAccessPoints.AccessPoint
的值将不会包含在最后。
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
var q = context.Set<AccessGroup>().AsNoTracking();
if (includeRelations)
{
q.Include(a => a.AccessGroupAccessPoints)
.ThenInclude(a => a.AccessPoint);
}
return q.ToListAsync();
}
我也尝试删除 .ThenInclude()
,使用字符串作为 .Include()
的参数,移动 .AsNoTracking()
来解决...这些选项都不起作用。
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
var q = context.Set<AccessGroup>();
if (includeRelations)
{
q.Include("AccessGroupAccessPoints");
}
return q.AsNoTracking().ToListAsync();
}
解决方案
但我找到了一个解决方案,如果在它评估对象列表之前不拆分查询,Entity Framework 将包含预期的属性。
希望对你有帮助。
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
if (includeRelations)
{
return context.Set<AccessGroup>()
.Include(a => a.AccessGroupAccessPoints).ThenInclude(a => a.AccessPoint)
.AsNoTracking()
.ToListAsync();
}
else
{
return context.Set<AccessGroup>().AsNoTracking().ToListAsync();
}
}
问题
为什么会这样?
这是 Entity Framework 错误吗?
出于类似的原因,这不会对列表进行适当的排序:
var x = new List<int> { 3, 2, 1 };
x.OrderBy(i => i);
Console.WriteLine(string.Join("|", x)); //prints 3,2,1
您需要捕获并使用 OrderBy 的结果才能生效:
var x = new List<int> { 3, 2, 1 };
var y = x.OrderBy(i => i);
Console.WriteLine(string.Join("|", y)); //prints 1,2,3
在你的第一个代码中,你创建 q
,然后你调用 Include()
,但不要使用 Include 中的 return 值,并且 Include 不会修改q
这样它就变成了包含的东西(就像在列表上调用 OrderBy 不会摇晃它的项目所以它们是有序的)所以你包含的原因的知识丢失了..
..然而,在您的第二个代码中,当您 运行 查询(由于链)
时,您使用 Include 中的 return 值
也许您需要这样的东西:
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
var q = context.AccessGroups.AsQueryable(); //so we can assign the IIncludableQueryable generated by Include.ThenInclude back to q
if (includeRelations)
{
q = q.Include(a => a.AccessGroupAccessPoints)
.ThenInclude(a => a.AccessPoint);
}
return q.ToListAsync();
}
场景
如果我拆分 Entity Framework linq 查询以首先评估 IQueryable
,然后再尝试包含一些属性,则 AccessGroupAccessPoints
和 AccessGroupAccessPoints.AccessPoint
的值将不会包含在最后。
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
var q = context.Set<AccessGroup>().AsNoTracking();
if (includeRelations)
{
q.Include(a => a.AccessGroupAccessPoints)
.ThenInclude(a => a.AccessPoint);
}
return q.ToListAsync();
}
我也尝试删除 .ThenInclude()
,使用字符串作为 .Include()
的参数,移动 .AsNoTracking()
来解决...这些选项都不起作用。
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
var q = context.Set<AccessGroup>();
if (includeRelations)
{
q.Include("AccessGroupAccessPoints");
}
return q.AsNoTracking().ToListAsync();
}
解决方案
但我找到了一个解决方案,如果在它评估对象列表之前不拆分查询,Entity Framework 将包含预期的属性。 希望对你有帮助。
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
if (includeRelations)
{
return context.Set<AccessGroup>()
.Include(a => a.AccessGroupAccessPoints).ThenInclude(a => a.AccessPoint)
.AsNoTracking()
.ToListAsync();
}
else
{
return context.Set<AccessGroup>().AsNoTracking().ToListAsync();
}
}
问题
为什么会这样?
这是 Entity Framework 错误吗?
出于类似的原因,这不会对列表进行适当的排序:
var x = new List<int> { 3, 2, 1 };
x.OrderBy(i => i);
Console.WriteLine(string.Join("|", x)); //prints 3,2,1
您需要捕获并使用 OrderBy 的结果才能生效:
var x = new List<int> { 3, 2, 1 };
var y = x.OrderBy(i => i);
Console.WriteLine(string.Join("|", y)); //prints 1,2,3
在你的第一个代码中,你创建 q
,然后你调用 Include()
,但不要使用 Include 中的 return 值,并且 Include 不会修改q
这样它就变成了包含的东西(就像在列表上调用 OrderBy 不会摇晃它的项目所以它们是有序的)所以你包含的原因的知识丢失了..
..然而,在您的第二个代码中,当您 运行 查询(由于链)
时,您使用 Include 中的 return 值也许您需要这样的东西:
public Task<List<AccessGroup>> GetAll(bool includeRelations)
{
var q = context.AccessGroups.AsQueryable(); //so we can assign the IIncludableQueryable generated by Include.ThenInclude back to q
if (includeRelations)
{
q = q.Include(a => a.AccessGroupAccessPoints)
.ThenInclude(a => a.AccessPoint);
}
return q.ToListAsync();
}