如何使用.net实现SQL IN()的等价物
在.net(c#或vb)表达式中,您将如何实现SQL的便捷IN()function?
即(1,2,4,7)中的值
而不是:
value = 1或value = 2或value = 4或value = 7
using System; using System.Linq; static class SqlStyleExtensions { public static bool In(this string me, params string[] set) { return set.Contains(me); } }
用法:
if (Variable.In("AC", "BC", "EA")) { }
我为此做了一个扩展方法,我觉得非常有用。 但是,它只包含现有IEnumerable.Contains()函数的语法糖。
/// /// Returns true if the value is represented in the provided enumeration. /// /// Type of the value /// The object to check if the enumeration contains /// The enumeration that might contain the object /// True if the object exists in the enumeration public static bool In(this T obj, IEnumerable values) { return values.Contains(obj); }
编辑:有人打败了我,该死的。 我会留在这里发帖,因为它是一个更通用的版本。
我知道这里有很多答案,但这是我对这个主题的看法,每天都在SubSonic中使用。 这是一种扩展方法:
public static IQueryable WhereIn( this IQueryable query, Expression> selector, params TValue[] collection) where T : class { if (selector == null) throw new ArgumentNullException("selector"); if (collection == null) throw new ArgumentNullException("collection"); ParameterExpression p = selector.Parameters.Single(); if (!collection.Any()) return query; IEnumerable equals = collection.Select(value => (Expression)Expression.Equal(selector.Body, Expression.Constant(value, typeof(TValue)))); Expression body = equals.Aggregate(Expression.Or); return query.Where(Expression.Lambda>(body, p)); }
和WhereNotIn:
public static IQueryable WhereNotIn( this IQueryable query, Expression> selector, params TValue[] collection) where T : class { if (selector == null) throw new ArgumentNullException("selector"); if (collection == null) throw new ArgumentNullException("collection"); ParameterExpression p = selector.Parameters.Single(); if (!collection.Any()) return query; IEnumerable equals = collection.Select(value => (Expression)Expression.NotEqual(selector.Body, Expression.Constant(value, typeof(TValue)))); Expression body = equals.Aggregate(Expression.And); return query.Where(Expression.Lambda>(body, p)); }
用法:
var args = new [] { 1, 2, 3 }; var bookings = _repository.Find(r => r.id > 0).WhereIn(x => x.BookingTypeID, args); // OR we could just as easily plug args in as 1,2,3 as it's defined as params var bookings2 = _repository.Find(r => r.id > 0).WhereIn(x => x.BookingTypeID, 1,2,3,90); var bookings3 = _repository.Find(r => r.id > 0).WhereNotIn(x => x.BookingTypeID, 20,30,60);
这真的让我每次回顾时都会微笑:)
吉姆
[编辑] – 最初源自SO,但修改为使用iqueryable和params: ‘Contains()’解决方法使用Linq to Entities?
if((new int[] {1, 2, 4, 7}).Contains(value)) { // Do some work. }
正如其他人所指出的那样,你可以创建一个In()扩展方法(我将它保持通用,这样你就可以在任何类型上使用它):
public static bool In(T this obj, IEnumerable col) { return col.Contains(obj); }
所以最初的例子变成了:
if(value.In(new int[] {1, 2, 4, 7})) { // Do some work. }
或者使用System.Linq
……
(VB.NET)
Enumerable.Contains({1, 2, 4, 7}, value)
要么
{1, 2, 4, 7}.Contains(value)
(C#)
Enumerable.Contains(new int[]{1, 2, 4, 7}, value);
要么
new int[] {1, 2, 4, 7}.Contains(value);
您可以在列表中使用Contains()方法。
int myValue = 1; List checkValues = new List { 1, 2, 3 }; if (checkValues.Contains(myValue)) // Do something
使用LINQ
var q = from x in collection where (new int[] { 1, 2, 4, 7}).Contains(x.value) select x
如果您将对同一数据集进行多次查找,那么从性能角度来看,使用HashSet
是很好的。
HashSet numbers = new HashSet { 1, 2, 4, 7 }; bool is5inSet = numbers.Contains(5);
这里有一些简单的Linq和一些伪代码。 无需重新发明轮子。
int[] values = new int[]{1, 2, 4, 7}; int target = 2; bool contains = values.Any(v => v == target);
或者像某些人建议的那样使用.Contains
。