我正在使用System.Linq.Dynamic来编写动态查询,但我无法弄清楚如何将list(IEnumerable)参数传递给查询: 这就是我想要实现的目标:
SELECT * FROM People WHERE Role IN ('Employee','Manager')
这里的Linq相当于同一个查询:
from person in People where (new string[]{"Employee","Manager"}).Contains(person.Role)
所以我想我可以使用动态Linq编写此查询:
People.Where("@0.Contains(Role)","(new string[]{\"Employee\",\"Manager\"})")
此版本无法正常使用:
People.Where("(new string[]{"Employee","Manager"}).Contains(Role)")
所以问题是:我如何应用Dynamic Linq Library来处理列表和/或IEnumerable参数,例如上面的场景?
答案 0 :(得分:2)
动态linq项目不支持'包含'本地,我有相同的要求,不得不下载源并修改它以支持它。
我已经失去了跟上任何nuget更新的能力,但该解决方案现在可以满足我们的需求。我无法找到我发现的地方,但这就是我做到的。
编辑dynamic.cs文件并将以下内容添加到第566行:
interface IEnumerableSignatures
{
bool Contains(object selector); // Add this
void Where(bool predicate);
//...
// Then around line 628 add a new keyword:
static readonly string keywordOuterIt = "outerIt";
static readonly string keywordIt = "It";
//...
// above ParameterExpression It; add
ParameterExpression outerIt;
// In ParseIdentifier add
if (value == (object)keywordOuterIt) return ParseOuterIt();
//Then add that method
Expression ParseOuterIt()
{
if (outerIt == null)
throw ParseError(Res.NoItInScope);
NextToken();
return outerIt;
}
// In ParseAggreggate, add:
outerIt = it;
if (signature.Name == "Min" || signature.Name == "Max")
{
typeArgs = new Type[] { elementType, args[0].Type };
}
else
{
typeArgs = new Type[] { elementType };
}
if (args.Length == 0)
{
args = new Expression[] { instance };
}
else
{
// add this section
if (signature.Name == "Contains")
args = new Expression[] { instance, args[0] };
else
{
args = new Expression[] { instance, Expression.Lambda(args[0], innerIt) };
}
}
// In CreateKeyWords()
d.Add(keywordOuterIt, keywordOuterIt); // Add this
我不知道我们是否可以在此处上传源代码,但我一直在维护自己的Dynamic.cs副本,并尝试使用nuget版本保持最新版本。如果你愿意,我很乐意上传它。我只是不记得我得到了所有这些,因为在动态linq上搜索包含主要产生错误的结果 - 指向字符串包含,而不是IEnumerable.contains。
答案 1 :(得分:1)
默认情况下,动态LINQ不支持Contains
。
你可以用旧的方式做到:
var roles = new[] { "Employee", "Manager" };
var predicate = new StringBuilder();
for (var i = 0; i < roles.Length; i++)
{
string role = roles[i];
predicate.AppendFormat("Role = @{0}", i);
if (i < roles.Length) predicate.Append(" OR ");
}
People.Where(predicate.ToString(), role.Cast<object>().ToArray());
以下是关于此的问题:link。在提到的问题中,还有其他替代品。
答案 2 :(得分:0)
我知道老问题,但我花了很长时间才解决。使用最新的 Dynamic-linq 在此处为其他人引用它: https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/314
所以:
final bytes = UriData.parse(base64Result).contentAsBytes();
这将生成 sql 如下:
List<string> ids = new List<string>(){ 1, 2, 3 };
List<string> stringIds = new List<string>(){ "test", "find", "something" };
var queryResults = context.someEntity.AsNoTracking();
queryResults = queryResults.Where("intColName in @0", ids);
queryResults = queryResults.Where("stringColName in @0", strings);
var results = await queryResults.ToListAsync();