[英]How to “split up” or optimize a Linq to Sql query.
我们有一个AdvancedSearchModel
,它只是一个带有多个字符串的结构。 SerialNumbers
是一串用逗号分隔的序列号(长度为10个字符)。 这被拆分为字符串数组。 我们正在搜索具有一列SerialNumber
Devices
表。 我们还需要对这些搜索短语进行部分匹配,以解释“ Any
和“ Contains
用法。 AdvancedSearchModel
中大约有10个字符串,我们可以将每个字符串毫无问题地应用于查询。
public static IQueryable<Device> ApplySearchQuery(IQueryable<Device> query, AdvancedSearchModel searchModel)
{
if (!String.IsNullOrWhiteSpace(searchModel.SerialNumbers))
{
string[] serialNumbers = searchModel.SerialNumbers.Split(',');
query = query.Where(d => serialNumbers.Any(s => d.SerialNumber.Contains(s)));
}
// ... more queries added that are part of the search model
}
让我以实施此操作为开头,我们希望一次最多搜索约10个序列号。 但是 ,我们发现用户最多输入100个序列号。 我们收到一个错误,即查询从此嵌套得太深了。 因此,即使我们仅按序列号进行搜索,当serialNumbers
超过43个元素时,它也会引发异常。
我不太确定如何拆分此查询,因为它们分别很简单(尽管我们期望结果很慢)。
也许我们可以有一个大约为25的string[]
的ArrayList
,并扩展此数组列表,即,如果用户搜索100个序列号,则ArrayList
将具有4个字符串数组,但是我不确定这是否真的有用。 ..
有任何想法吗?
我想如果您手动生成OR表达式,则可以让EF生成平面OR语句而不是嵌套的子查询:
string[] serialNumbers = searchModel.SerialNumbers.Split(',');
// GetMethod defined at http://www.codeducky.org/10-utilities-c-developers-should-know-part-two/
var stringContainsMethod = Helpers.GetMethod((string s) => s.Contains(default(string)));
var serialNumberProperty = Helpers.GetProperty((Device d) => d.SerialNumber);
var parameter = Expression.Parameter(typeof(Device));
// generate a condition d.SerialNumber.Contains(sn) for each sn
var conditions = serialNumbers.Select(sn => Expression.Call(
Expression.MakeMemberAccess(parameter, serialNumberProperty), // d.SerialNumber
stringContainsMethod, // the method to invoke
Expression.Constant(sn) // equivalent of a string literal for the serial number
));
// generate a lambda we can pass to Where:
// d => d.SerialNumber.Contains(sn1) || d.SerialNumber.Contains(sn1) || ..
var predicate = Expression.Lambda<Func<Device, bool>>(
// merge each condition with ORs
conditions.Aggregate<Expression>((c1, c2) => Expression.OrElse(c1, c2)),
parameter
);
// apply the predicate
query = query.Where(predicate);
批处理当然也可以。 但是,对于这么小的参数集,则没有必要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.