我有一个搜索框,我已将数据分解为单词。我现在需要将每个单词与数据库中的几个字段进行比较。这是我的代码:
List<string> searchValues = searchString.Split(delimiters, StringSplitOptions.RemoveEmptyEntries).ToList();
using (DatabaseEntities context = new DatabaseEntities())
{
IQueryable<DatabaseType> returnValue =
context.DatabaseType.Where(y =>
y.Field1.Contains(searchValues[0]) ||
y.Field1.Contains(searchValues[0]));
searchValues.Skip(1).ToList().ForEach(x =>
{
returnValue = returnValue.Where(y =>
y.Field1.Contains(x) ||
y.Field2.Contains(x));
});
return returnValue.ToList();
我的目标是在将项目实际加载到内存之前构建完整查询。但是,当我尝试运行它时,我收到以下错误:
System.NotSupportedException: LINQ to Entities does not recognize the method 'System.String get_Item(Int32)' method, and this method cannot be translated into a store expression.
我原以为这种类型的错误意味着我尝试的操作在转换为SQL时不起作用,但我很确定我之前使用过Contains作为LIKE语句。此外,数据库中的所有信息都是nvarchars,因此这些信息等同于我的Entity中的字符串。有没有人知道问题是什么?使用IQueryable是最好的方法吗?如果可能的话,我宁愿懒得加载所有这些。
答案 0 :(得分:2)
get_Item(Int32)调用将成为列表的索引。在你的情况下,他们是searchValues [0]。使用:
var searchValue = searchValues[0];
IQueryable<DatabaseType> returnValue =
context.DatabaseType.Where(y =>
y.Field1.Contains(searchValue) ||
y.Field1.Contains(searchValue));
答案 1 :(得分:0)
我使用下面的扩展方法为Linq to Entities构建Contains类型表达式(在注释中引用原始源代码)。我认为它也适用于这种情况。
/// <summary>
/// Extension method that enables .Contains(obj) like functionality for Linq to Entities.
///
/// Source: http://www.velocityreviews.com/forums/t645784-linq-where-clause.html
/// </summary>
/// <typeparam name="TElement">The element being evaluated by the Where clause</typeparam>
/// <typeparam name="TValue">The value to match</typeparam>
/// <param name="valueSelector">Lamda for selecting matching values</param>
/// <param name="values">IEnumerable of the values</param>
/// <returns>Expression consumable by Linq to Entities that reflects semantics of .Contains(value)</returns>
/// <remarks>
/// Usage:
///
/// Replace expression like
///
/// where ChildrenIDs.Contains(items.CategoryID)
///
/// with
///
/// .Where((BuildContainsExpression<Item, int>(item => item.CategoryID, ChildrenIDs))
///
/// NOTE: If the item collection is large, the SQL query will be as well.
/// </remarks>
static public Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values) { throw new ArgumentNullException("values"); }
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
示例用法:
var exprWithContains =
LinqToEntitiesUtil.BuildContainsExpression<List<int?>, int?>
(p => p.ProductYear, productYears);
var result = (from p in products select p).Where(exprWithContains);