gpt4 book ai didi

c# - 如何在构建 EF 查询时将 WHERE 条件应用于 EF .Include()

转载 作者:太空狗 更新时间:2023-10-29 23:37:15 26 4
gpt4 key购买 nike

我有以下两个类:

public class Rule
{
public int Id { get; set; }
public string RuleValue { get; set; }
public bool IsActive { get; set; }
public SharedRuleType RuleType { get; set; }
public List<Exclusion> Exclusions { get; set; }
}

public class Exclusion
{
public int Id { get; set; }
public int InstanceId { get; set; }
public int SiteId { get; set; }
[ForeignKey( "RuleId" )]
public int RuleId { get; set; }
public Rule Rule { get; set; }
}

然后我有一个 EF 查询返回“所有事件”Rules,我需要它为每个 Rule 包含 Exclusions (如果有的话)但仅限已分配指定 InstanceIdExclusions。因此过滤是针对 Exclusions 属性进行的,而不是过滤掉 Rules

在构建 EF 查询时,我还需要考虑一些条件。

这是我目前的查询:

public async Task<List<Rule>> GetRules(int instanceId, SharedRuleType ruleType, string searchTerm)
{
using ( var context = new MyDbContext() )
{
var query = context.Set<Rule>()
.Include( r => r.Exclusions ) // *** Currently returns ALL exclusions but I only want ones where InstanceId == instanceId(param) ***
.Where( r => r.IsActive );

if ( !string.IsNullOrEmpty( searchTerm ) )
{
query = query.Where( r => r.RuleValue.Contains( searchTerm ) );
}

if ( ruleType != SharedRuleType.None )
{
query = query.Where( r => r.RuleType == ruleType );
}

return await query.ToListAsync();
}
}

我尝试在 .Include() 中应用 .Where 以尝试仅包含相关的 Exclusions(基于 instanceId)但发现你不能那样做。我四处寻找,发现了一些人们使用匿名类型的示例,但我无法像我在这里所做的那样逐个构建查询时使它正常工作。

所以,我不知道如何完成此操作,因为我真的不想为每个 Rule 返回“每个”Exclusion,当我不不需要返回每个 Exclusion

最佳答案

Include 方法不能像您尝试的那样使用过滤器。

解决方案 #1

免责声明:我是项目的所有者Entity Framework Plus

EF+ Query IncludeFilter 特性允许过滤相关实体。

public async Task<List<Rule>> GetRules(int instanceId, SharedRuleType ruleType, string searchTerm)
{
using ( var context = new MyDbContext() )
{
var query = context.Set<Rule>()
.IncludeFilter( r => r.Exclusions.Where(x => x.InstanceId == instanceId))
.Where( r => r.IsActive );

// ... code ...

维基:EF+ Query IncludeFilter

解决方案#2

另一种技术是使用投影(这是我的图书馆在幕后所做的)

public async Task<List<Rule>> GetRules(int instanceId, SharedRuleType ruleType, string searchTerm)
{
using ( var context = new MyDbContext() )
{
var query = context.Set<Rule>()
.Where( r => r.IsActive );

if ( !string.IsNullOrEmpty( searchTerm ) )
{
query = query.Where( r => r.RuleValue.Contains( searchTerm ) );
}

if ( ruleType != SharedRuleType.None )
{
query = query.Where( r => r.RuleType == ruleType );
}


// ToListAsync has been removed to make the example easier to understand
return query.Select(x => new { Rule = x,
Exclusions = x.Exclusions.Where(e => e.InstanceId == instanceId)
})
.ToList()
.Select(x => x.Rule)
.ToList();
}
}

编辑:回答子问题#1

如何在前面的示例中使用 ToListAsync

您只需等待第一个列表

return  (await query.Select(x => new { Rule = x,
Exclusions = x.Exclusions.Where(e => e.InstanceId == instanceId)
})
.ToListAsync())
.Select(x => x.Rule)
.ToList();

编辑:回答子问题#2

如何根据规则执行 Skip、Take、OrderBy

你和平时一样做

return  (await query.Take(15)
.Skip(5)
.OrderBy(x => x.RuleId)
.Select(x => new { Rule = x,
Exclusions = x.Exclusions.Where(e => e.InstanceId == instanceId)
})
.ToListAsync())
.Select(x => x.Rule)
.ToList();

关于c# - 如何在构建 EF 查询时将 WHERE 条件应用于 EF .Include(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37719666/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com