我是LINQ的新手,所以我在这里很困惑。我有一个数据库,并尝试运行以下代码。
IQueryable<decimal> location_ids = (from m in _db.Admins
where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d")
select m.LocationId);
if (!location_ids.Contains(new Decimal(conf.umisteni.Budova.ID)))
在if语句中,我得到一个错误,我不明白,也不知道,如何解决它:
System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean Contains[Decimal](System.Linq.IQueryable`1[System.Decimal], System.Decimal)' method, and this method cannot be translated into a store expression.
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
有什么想法吗?
答案 0 :(得分:8)
使用Linq-to-Objects IEnumerable将允许您对查询结果使用Contains(Decimal)。
IEnumerable<decimal> location_ids = (from m in _db.Admins
where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d")
select m.LocationId);
但是,为什么不扩展where子句:
IEnumerable<decimal> location_ids = (from m in _db.Admins
where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d") && (m.LocationId == conf.umisteni.Budova.ID)
select m.LocationId);
if (!location_ids.Any())
答案 1 :(得分:1)
Linq 2 sql无法将ids.Contains()方法转换为sql。 您可以执行以下操作:
if(!location_ids.ToList().Contains(new Decimal(conf.umisteni.Budova.ID)))
这将触发sql查询,将它们放在对象中并在本地执行包含。
另一个解决方案是将conf.umisteni.Budova.Id放在Where子句中(使用等号,而不是包含),然后添加.any
if((from m in _db.Admins
where m.UserId.Equals(conf.umisteni.Budova.ID.ToString())
select m.LocationId).Any())
如果您之后不需要任何密钥,这只是个好主意。
答案 2 :(得分:1)
这是一个帮助方法,它在Linq to Entities的上下文中提供.Contains()的所有优点
public static class LinqToEntitiesUtil
{
/// <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);
}
}
答案 3 :(得分:0)
我有点类似的东西。您的System.Data.dll可能不是同一版本。我的开发机器支持该方法,但是当我部署到测试机器时,我遇到了运行时错误。 System.Data.dll版本较旧。向后兼容的方法是一个很好的解决方案。但我仍然想要追踪差异,必须应用一些不在其他环境中的补丁。谁知道如果不加以控制,这会导致其他问题。