zoukankan      html  css  js  c++  java
  • LINQ to Entities 实现sql 关键字"In"方式总结

    在LINQ to Entities中没有办法再像 LINQ to SQL 中一样使用 Contains 的方法来实现sql "in" 关键字

    下面代码在 LINQ to SQL 中可行 在LINQ to Entities却无法运行: 

    var s = db.Account.Select(c => c.ID);
    var ret 
    =(from t in db.Profile
     
    where s.Contains(t.ID)
     select t).ToList();

    替代方法1:使用方法Any

    var ids=db.Account.Select(c => c.ID);
    var ret 
    = (from t in db.Profile where ids.Any(c=>c==t.UserID) select t).ToList();

    使用方法Any替换法搞了好久都没法实现直接对数组Any,下列代码仍无法执行:

    int[] ids = new int[]{10101,10005,10007};
    var ret 
    = (from t in db.Profile where ids.Any(c=>c==t.UserID) select t).ToList();

    于是继续Goolge寻找第二种方法,在MSDN论坛上找一个构造Lambda语句的方法
    替代方法2:构造Lambda语句

            private static Expression<Func<TElement, bool>> BuildWhereInExpression<TElement, TValue>(Expression<Func<TElement, TValue>> propertySelector, IEnumerable<TValue> values)
            {
                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);
            }

    调用方法:

    int[] ids = new int[]{10101,10005,10007};
    db.Profile.Where(BuildWhereInExpression
    <Profile,int>(v=>v.Id,ids);

    该方法可也扩展为:

            public static IQueryable<TElement> WhereIn<TElement, TValue>(this IQueryable<TElement> source, Expression<Func<TElement, TValue>> propertySelector, params TValue[] values)
            {
                
    return source.Where(BuildWhereInExpression(propertySelector, values));
            }

    这样就可以直接使用下列方法调用

    string[] ids = new string[]{10101,10005,10007};
    db.Profile.WhereNotIn(c 
    => c.Id,ids);

    后来又看到网上有这样的解决办法
    替代方法3:字符串构造
    这个方法比较简单

    string[] ids = new string[]{10101,10005,10007};
    string csvIds = string.Join(",", ids.Cast<string>().ToArray());
    db.Profile.Where(
    "it.Id in {"+csvIds+"}");

    it是什么这里就不用说了吧!

  • 相关阅读:
    js获取当前时间,日期格式为年月日
    create-react-app里添加less
    react css 模块化
    react 点击父级元素 不触发子级元素click事件
    react-router-dom 实现路由左右滑动进入页面的效果
    vue路由左右侧滑动 react路由左右侧滑动
    react 父组件不能直接在子组件上加className,也得用props传递过去
    react 父组件调用子组件方法
    css滚动相关问题记录
    javascript异步编程的几种方法
  • 原文地址:https://www.cnblogs.com/ejiyuan/p/1527224.html
Copyright © 2011-2022 走看看