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是什么这里就不用说了吧!

posted @   ejiyuan  阅读(18589)  评论(30编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示