我正在尝试使用Silverlight ADO.Net数据服务客户端api(以及Linq To Entities)创建一个使用where子句中的id列表的查询.有没有人知道Contains不受支持的解决方法?
我想做这样的事情:
ListtxnIds = new List (); // Fill list var q = from t in svc.OpenTransaction where txnIds.Contains(t.OpenTransactionId) select t;
试过这个:
var q = from t in svc.OpenTransaction where txnIds.Any(tt => tt == t.OpenTransactionId) select t;
但得到"方法'任何'不受支持".
更新: EF≥4 ">Contains
直接支持(Checkout ">Any
),因此您不需要任何解决方法.
public static IQueryableWhereIn ( this ObjectQuery query, Expression > selector, IEnumerable collection ) { if (selector == null) throw new ArgumentNullException("selector"); if (collection == null) throw new ArgumentNullException("collection"); if (!collection.Any()) return query.Where(t => false); ParameterExpression p = selector.Parameters.Single(); IEnumerable equals = collection.Select(value => (Expression)Expression.Equal(selector.Body, Expression.Constant(value, typeof(TValue)))); Expression body = equals.Aggregate((accumulate, equal) => Expression.Or(accumulate, equal)); return query.Where(Expression.Lambda >(body, p)); } //Optional - to allow static collection: public static IQueryable WhereIn ( this ObjectQuery query, Expression > selector, params TValue[] collection ) { return WhereIn(query, selector, (IEnumerable )collection); }
用法:
public static void Main() { using (MyObjectContext context = new MyObjectContext()) { //Using method 1 - collection provided as collection var contacts1 = context.Contacts.WhereIn(c => c.Name, GetContactNames()); //Using method 2 - collection provided statically var contacts2 = context.Contacts.WhereIn(c => c.Name, "Contact1", "Contact2", "Contact3", "Contact4" ); } }
您可以在手边编写一些e-sql(请注意关键字"it"):
return CurrentDataSource.Product.Where("it.ID IN {4,5,6}");
这是我用来从集合YMMV生成一些e-sql的代码:
string[] ids = orders.Select(x=>x.ProductID.ToString()).ToArray(); return CurrentDataSource.Products.Where("it.ID IN {" + string.Join(",", ids) + "}");
来自MSDN:
static Expression> BuildContainsExpression ( Expression > valueSelector, IEnumerable values) { if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); } if (null == values) { throw new ArgumentNullException("values"); } ParameterExpression p = valueSelector.Parameters.Single(); // p => valueSelector(p) == values[0] || valueSelector(p) == ... 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 ((accumulate, equal) => Expression.Or(accumulate, equal)); return Expression.Lambda >(body, p); }
并且查询变为:
var query2 = context.Entities.Where(BuildContainsExpression(e => e.ID, ids));