转自:http://kb.cnblogs.com/a/1527224/
http://www.cnblogs.com/ejiyuan/
方法1 比较局限(未深究的结论), 只适用于 in ObjectQuery<T> where T:Entity,换做 IEnumerable<T>(往往我们需要从Silverlight端传IEnumerable<T>到Server端),便会提示如下错误:
base {System.SystemException} = {"Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."}
方法2 很受用
方法3 Where:ObjectQurey.Where
原文如下:
在LINQ to Entities中没有办法再像 LINQ to SQL 中一样使用 Contains 的方法来实现sql "in" 关键字
下面代码在 LINQ to SQL 中可行 在LINQ to Entities却无法运行:
var ret = (from t in db.Profile
where s.Contains(t.ID)
select t).ToList();
替代方法1:使用方法Any
var ret = (from t in db.Profile where ids.Any(c => c == t.UserID) select t).ToList();
使用方法Any替换法搞了好久都没法实现直接对数组Any,下列代码仍无法执行:
var ret = (from t in db.Profile where ids.Any(c => c == t.UserID) select t).ToList();
于是继续Goolge寻找第二种方法,在MSDN论坛上找一个构造Lambda语句的方法
替代方法2:构造Lambda语句
{
ParameterExpression p = propertySelector.Parameters.Single();
if ( ! values.Any())
return e => false ;
var equals = values.Select(value => (Expression)Expression.Equal(propertySelector.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);
}
调用方法:
db.Profile.Where(BuildWhereInExpression < Profile, int > (v => v.Id,ids);
该方法可也扩展为:
{
return source.Where(BuildWhereInExpression(propertySelector, values));
}
这样就可以直接使用下列方法调用
db.Profile.WhereIn(c => c.Id,ids);
后来又看到网上有这样的解决办法
替代方法3:字符串构造
这个方法比较简单
string csvIds = string .Join( " , " , ids.Cast < string > ().ToArray());
db.Profile.Where( " it.Id in { " + csvIds + " } " );
it是什么这里就不用说了吧!