2010-08-04 36 views
16

实现等效的SQL IN()在.net(c#或vb)表达式中,您将如何实现SQL的方便的IN()功能?如何使用.net

在(1,2,4,7)

而非

即值:

值= 1或值= 2或值= 4或值= 7

+0

什么版本的.NET框架? – 2010-08-04 13:56:14

+0

我主要使用3.5。不确定4.0版本中是否存在使得这更容易的对话框? – 2010-08-04 14:03:59

回答

21
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")) 
{ 

} 
+3

你也可以使字符串的一个通用参数... – ngoozeff 2010-08-04 14:01:36

+0

PARAMS使呼叫真正整齐。 – 2010-08-06 16:52:25

+3

通用版本 - public static bool在(this T me,params T [] List) – 2010-08-06 22:14:45

4
if((new int[] {1, 2, 4, 7}).Contains(value)) 
{ 
    // Do some work. 
} 

正如其他人所指出的,Y OU可以创建一个在()扩展方法(我会保持它通用的,所以你可以在任何类型的使用):

public static bool In<T>(T this obj, IEnumerable<T> col) 
{ 
    return col.Contains(obj); 
} 

所以最初的例子变成:

if(value.In(new int[] {1, 2, 4, 7})) 
{ 
    // Do some work. 
} 
+0

没有'Array.Contains'方法。 – Conrad 2013-05-20 19:55:49

+0

@Conrad - 它作为LINQ Enumerable扩展方法的一部分存在。 http://msdn.microsoft.com/en-us/library/system.linq.enumerable.contains.aspx – 2013-05-20 19:57:15

+0

啊。好吧,它的确如此。 – Conrad 2013-05-20 20:02:16

11

我做了一个我发现这个扩展方法非常有用。然而,它不比包装现有IEnumerable.Contains()函数的语法糖多得多。

/// <summary> 
/// Returns true if the value is represented in the provided enumeration. 
/// </summary> 
/// <typeparam name="T">Type of the value</typeparam> 
/// <param name="obj">The object to check if the enumeration contains</param> 
/// <param name="values">The enumeration that might contain the object</param> 
/// <returns>True if the object exists in the enumeration</returns> 
public static bool In<T>(this T obj, IEnumerable<T> values) { 
    return values.Contains(obj); 
} 

编辑: 有人打我,它该死。 虽然这是一个更通用的版本,我会继续在这里发布。

+0

wasatz - 我发布了一个以下的版本,扩展到完整表达式和lambda功能。如果你正在使用任何IQueryables,试试它可能会很好。 – 2010-08-04 15:51:40

2

您可以在列表上使用Contains()方法。

int myValue = 1; 
    List<int> checkValues = new List<int> { 1, 2, 3 }; 

    if (checkValues.Contains(myValue)) 
     // Do something 
2

使用LINQ

var q = from x in collection 
     where (new int[] { 1, 2, 4, 7}).Contains(x.value) 
     select x 
1

如果你会做对同一数据集众多查找这是好事从性能的角度使用HashSet<T>

HashSet<int> numbers = new HashSet<int> { 1, 2, 4, 7 }; 
bool is5inSet = numbers.Contains(5); 
8

我知道这里有答案的答案,但这里是我对这个问题的看法,每天在SubSonic中使用。这是一个扩展方法:

public static IQueryable<T> WhereIn<T, TValue>(
       this IQueryable<T> query, 
       Expression<Func<T, TValue>> 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<Expression> 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<Func<T, bool>>(body, p)); 
} 

和WhereNotIn:

public static IQueryable<T> WhereNotIn<T, TValue>(
       this IQueryable<T> query, 
       Expression<Func<T, TValue>> 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<Expression> 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<Func<T, bool>>(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()' workaround using Linq to Entities?

+0

+1非常好! – wasatz 2010-08-05 08:21:49

4

或者使用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); 
+0

就是这样:'{1,2,4,7} .Contains(value)'。 – Neolisk 2013-04-11 00:04:08

1

下面是一些简单的LINQ一些伪代码。不需要重新发明轮子。

int[] values = new int[]{1, 2, 4, 7}; 
int target = 2; 
bool contains = values.Any(v => v == target); 

或使用.Contains,如某些人所建议的。