2010-08-04 16 views
16

Trong các biểu thức .net (C# hoặc vb), bạn sẽ triển khai thực hiện hàm IN() tiện dụng của SQL như thế nào?Làm thế nào để bạn thực hiện tương đương với SQL IN() bằng cách sử dụng .net

tức là giá trị trong (1, 2, 4, 7)

hơn:

value = 1 hoặc giá trị = 2 hoặc value = 4 hoặc value = 7

+0

phiên bản .NET framework nào? –

+0

Tôi chủ yếu sử dụng 3.5. Bạn không chắc chắn nếu có anthing trong 4.0 mà làm cho điều này dễ dàng hơn? –

Trả lời

21
using System; 
using System.Linq; 

static class SqlStyleExtensions 
{ 
    public static bool In(this string me, params string[] set) 
    { 
     return set.Contains(me); 
    } 
} 

Cách sử dụng :

if (Variable.In("AC", "BC", "EA")) 
{ 

} 
+3

Bạn cũng có thể làm cho chuỗi một tham số chung ... – ngoozeff

+0

params làm cho cuộc gọi thực sự gọn gàng. –

+3

Phiên bản chung - bool tĩnh công cộng Trong (T này, thông số T [] Danh sách) –

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

Như những người khác đã chỉ ra, y ou có thể tạo ra một phương pháp mở rộng Trong() (Tôi sẽ giữ nó chung chung, do đó bạn có thể sử dụng nó trên bất kỳ loại):

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

Vì vậy, ví dụ ban đầu trở thành:

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

Không có phương thức 'Array.Contains'. – Conrad

+0

@Conrad - Nó tồn tại như một phần của phương pháp mở rộng LINQ Enumerable. http://msdn.microsoft.com/en-us/library/system.linq.enumerable.contains.aspx –

+0

Ahh. Ok, vậy là vậy. – Conrad

11

Tôi đã thực hiện một phương pháp mở rộng cho điều này mà tôi thấy khá hữu ích. Tuy nhiên, nó không phải là nhiều hơn so với cú pháp đường gói các IEnumerable.Contains hiện có() chức năng.

/// <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); 
} 

Chỉnh sửa: Có người đánh tôi với nó, chết tiệt. Tôi sẽ giữ bằng cách đăng bài ở đây mặc dù vì nó là một phiên bản chung chung hơn.

+0

wasatz - tôi đã đăng một phiên bản dưới đây được mở rộng để biểu hiện đầy đủ và chức năng lambda. có thể là tốt đẹp để thử nó như là một thay thế nếu bạn đang sử dụng bất kỳ IQueryables –

2

Bạn có thể sử dụng phương thức Contains() trong danh sách.

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

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

Sử dụng LINQ

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

Nếu bạn sẽ làm được nhiều tra cứu trên các tập dữ liệu tương tự nó là tốt từ góc độ hiệu suất sử dụng HashSet<T>.

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

Tôi biết có vô số câu trả lời ở đây, nhưng đây là quan điểm của tôi về đề tài này, được sử dụng hàng ngày trong cận âm. nó là một phương pháp khuyến nông:

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)); 
} 

và 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)); 
} 

sử dụng:

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); 

điều này thực sự khiến tôi mỉm cười mỗi khi tôi xem lại nó :)

jim

[sửa] - ban đầu có nguồn gốc từ đây trên SO nhưng sửa đổi để sử dụng params IQueryable và: 'Contains()' workaround using Linq to Entities?

+0

+1 Thực sự tốt đẹp! – wasatz

4

Hoặc sử dụng System.Linq ...

(VB.NET)

Enumerable.Contains({1, 2, 4, 7}, value) 

hoặc

{1, 2, 4, 7}.Contains(value) 

(C#)

Enumerable.Contains(new int[]{1, 2, 4, 7}, value); 

hoặc

new int[] {1, 2, 4, 7}.Contains(value); 
+0

Chỉ điều này: '{1, 2, 4, 7} .Contains (value)'. – Neolisk

1

Dưới đây là một số đơn giản LINQ với một số mã giả. Không cần phải sáng chế lại bánh xe.

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

Hoặc sử dụng .Contains như một số gợi ý.

Các vấn đề liên quan