gpt4 book ai didi

c# - 如何动态组合 linq 查询?

转载 作者:太空宇宙 更新时间:2023-11-03 19:18:06 24 4
gpt4 key购买 nike

假设我有一个表,其中包含字符串 (nvarchar) 列中的格式化值。这些值应该是由一些 const 符号分隔的字符串(让它是一个分号 ;)。例如,

12;0;5;dog //four values separated by a semi-colon

053 //if there is only one value, no semi-colon at the end

分隔符永远是分隔符,它不能是值的一部分。

我需要检查该表中是否已经有一行,该列中有一个值列表,其中至少包含一个指定的项目。换句话说,我有一个值列表:

List<string> list = new List<string>() { "somevalue1", "somevalue2" };

分隔符:

string separator = ";";

我需要编写一个 linq-to-sql 查询来执行此操作:

select ... from sometable
where Value='somevalue1' or Value like 'somevalue1;%' or
Value like '%;somevalue1' or Value like '%;somevalue1;%'

or Value='somevalue2' or Value like 'somevalue2;%' or
Value like '%;somevalue2' or Value like '%;somevalue2;%'

应该提到的是,任何搜索到的值都可能包含另一个。也就是说,我可能正在搜索恰好 5,而某些行可能包含 1;15;55。这样的行必须​​是匹配项。 ...;5;... 或只是 5,或 5;...,或 ...; 5 是匹配项。

使用 linq-to sql 我知道如何进行以下类型的查询:

select ... from sometable where (... or ... or ...) and (... or ...) ...

也就是

IQueryable<SomeTable> query = dc.SomeTable;
foreach (string l in list)
{
string s = l;
query = query.Where(b => b.Value.StartsWith(s + separator) ||
b.Value.EndsWith(separator + s) ||
b.Value.Contains(separator + s + separator) ||
b.Value.Equals(s));
}
if (query.Any()) {/*...*/}

显然 Where 语句在生成的 sql 查询中与 AND 连接,而我到处都需要 OR

那么有没有办法在 C# 代码中获取我需要的查询?或者唯一的方法是使用手写查询和 DataContext.ExecuteQuery Method 来完成此操作?

最佳答案

public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>(
this IEnumerable<Expression<Func<T, bool>>> filters)
{
Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault();
if (firstFilter == null)
{
Expression<Func<T, bool>> alwaysTrue = x => true;
return alwaysTrue;
}

var body = firstFilter.Body;
var param = firstFilter.Parameters.ToArray();
foreach (var nextFilter in filters.Skip(1))
{
var nextBody = Expression.Invoke(nextFilter, param);
body = Expression.OrElse(body, nextBody);
}
Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param);
return result;
}

因此,您可以从输入集中轻松构建过滤器列表:

List<string> list = new List<string>() { "somevalue1", "somevalue2" };
List<Expression<Func<SomeTable, bool>>> equalsFilters = list
.Select(s => row => row.Value == s).ToList();
List<Expression<Func<SomeTable, bool>>> startsWithFilters = list
.Select(s => row => row.Value.StartsWith(s + ";")).ToList();
List<Expression<Func<SomeTable, bool>>> endsWithFilters = list
.Select(s => row => row.Value.EndsWith(";" + s).ToList();
List<Expression<Func<SomeTable, bool>>> middleFilters = list
.Select(s => row => row.Value.Contains(";" + s + ";")).ToList();

Expression<Func<SomeTable, bool>> theFilter = OrTheseFiltersTogether(
equalsFilters.Concat(startsWithFilters).Concat(endsWithFilters).Concat(middleFilters)
);

query = query.Where(theFilter);

关于c# - 如何动态组合 linq 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14556544/

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