c# - EF6:如何创建一个谓词来检查属性是否包含在对象列表的属性中
问题描述
我有以下情况:我有一个必须调用的函数:
class WorkobjectRepository...
public async Task<IList<WorkobjectView>> FindAllMatchingAsync(Expression<Func<WorkobjectView, bool>> whereExpression)
{
return await this.WorkobjectContext.WorkobjectViews.AsNoTracking().Where(whereExpression).ToListAsync();
}
WorkobjectView
除了其他属性之外,该类还具有以下两个属性:
1. StatusDetailedDisplayName
2. AssignedSubteamId
现在我想要所有WorkobjectView
s whereStatusDetailedDisplayName == StatusDetailedDisplay.activeOpen
和AssignedSubteamId
包含在具有属性的对象UserAccountSubteam
列表UserAccountSubteam
中Id
。
以下代码对我来说成功:
// List<UserAccountSubteam> caredTeams, which is given
String[] teams = new string[caredTeams.Count];
for (int i = 0; i < caredTeams.Count; i++)
{
teams[i] = caredTeams[i].Id;
}
return await this.WorkobjectRepository.FindAllMatchingAsync(w => w.StatusDetailedDisplayName == StatusDetailedDisplay.activeOpen && teams.Contains(w.AssignedSubteamId));
现在,我想使用LINQ
或使用集合函数来优化代码。
选项 1:第一个是使用LINQ
andExists
方法:
var results = await this.WorkobjectRepository.FindAllMatchingAsync(w => w.StatusDetailedDisplayName == StatusDetailedDisplay.activeOpen && caredTeams.Exists(team => team.Id == w.AssignedSubteamId));
但这失败了,我收到以下错误消息:
LINQ to Entities does not recognize the method 'Boolean Exists(System.Predicate`1[Backend.DomainLayer.UserAccountSubteam])' method, and this method cannot be translated into a store expression.
选项2:然后,我尝试使用Any
:
var results = await this.WorkobjectRepository.FindAllMatchingAsync(w => w.StatusDetailedDisplayName == StatusDetailedDisplay.activeOpen && caredTeams.Any(team => team.Id == w.AssignedSubteamId));
这也失败了:
Unable to create a constant value of type 'Backend.DomainLayer.UserAccountSubteam'. Only primitive types or enumeration types are supported in this context.
选项 3:最后但并非最不重要的是,我尝试了以下方法,但也失败了:
var results = await this.WorkobjectRepository.FindAllMatchingAsync(w => w.StatusDetailedDisplayName == StatusDetailedDisplay.activeOpen && caredTeams.Select(c => c.Id).Contains(w.AssignedSubteamId));
错误信息:
Unable to create a constant value of type 'Backend.DomainLayer.UserAccountSubteam'. Only primitive types or enumeration types are supported in this context.
实现这一目标的正确方法是什么?请注意,我无法更改基本功能FindAllMatchingAsync
。
解决方案
第一个选项Contains
是正确的方法,但可以简化。
var teams = caredTeams.Select(t => t.Id);
return await this.WorkobjectRepository
.FindAllMatchingAsync(w => w.StatusDetailedDisplayName == StatusDetailedDisplay.activeOpen
&& teams.Contains(w.AssignedSubteamId));
推荐阅读
- matlab - 使用 Matlab 的 lsqcurvefit 计算无限弛豫谱
- javascript - 如何从 jquery 中的多个选择器创建对象?
- r - R中用户定义函数的问题
- python-3.x - 第二次传递.format()时出现Python KeyError
- go - 对普罗米修斯的理解
- ffmpeg - 使用 ffmpeg 直播到 Youtube
- c# - 在 Foreach 循环中获取的数据集/JSON 非常慢,看起来不像是数据库调用的问题
- maven - apache spark中的阴影hadoop
- wordpress - 如何从永久链接中删除“index.php”[作曲家上的 WordPress]
- ios - 错误域 = PlugInKit 代码 = 13 “查询已取消” UserInfo = {NSLocalizedDescription = 查询已取消} 与 Objective C Xcode 9.3 iOS 11