Nelle espressioni .net (C# o vb), come implementeresti la comoda funzionalità IN() di SQL?Come implementare l'equivalente di SQL IN() utilizzando .net
ossia il valore d'(1, 2, 4, 7)
anziché:
value = 1 o value = valore 2 o = 4 o value = 7
Nelle espressioni .net (C# o vb), come implementeresti la comoda funzionalità IN() di SQL?Come implementare l'equivalente di SQL IN() utilizzando .net
ossia il valore d'(1, 2, 4, 7)
anziché:
value = 1 o value = valore 2 o = 4 o value = 7
using System;
using System.Linq;
static class SqlStyleExtensions
{
public static bool In(this string me, params string[] set)
{
return set.Contains(me);
}
}
Usage :
if (Variable.In("AC", "BC", "EA"))
{
}
Si può anche impostare la stringa come parametro generico ... I parametri – ngoozeff
rendono la chiamata veramente accurata. –
Versione generica - public static bool In
if((new int[] {1, 2, 4, 7}).Contains(value))
{
// Do some work.
}
Come altri hanno sottolineato, y ou potrebbe creare un metodo di estensione In() (lo terrò generico in modo da poter utilizzare su qualsiasi tipo):
public static bool In<T>(T this obj, IEnumerable<T> col)
{
return col.Contains(obj);
}
Quindi l'esempio iniziale diventa:
if(value.In(new int[] {1, 2, 4, 7}))
{
// Do some work.
}
ho fatto un metodo di estensione per questo che trovo abbastanza utile. Tuttavia, non è molto più dello zucchero sintattico che avvolge la funzione IEnumerable.Contains() esistente.
/// <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);
}
Edit: Qualcuno mi ha battuto ad esso, dannazione. Qui manterrò per posta visto che è una versione più generica.
wasatz - ho pubblicato una versione di seguito estesa alle funzionalità full expression e lambda. potrebbe essere bello provarlo come alternativa se stai usando qualsiasi IQueryables –
È possibile utilizzare il metodo Contains() nell'elenco.
int myValue = 1;
List<int> checkValues = new List<int> { 1, 2, 3 };
if (checkValues.Contains(myValue))
// Do something
utilizzando LINQ
var q = from x in collection
where (new int[] { 1, 2, 4, 7}).Contains(x.value)
select x
Se si farà molte ricerche sullo stesso insieme di dati è un bene dal punto di vista delle prestazioni da utilizzare HashSet<T>
.
HashSet<int> numbers = new HashSet<int> { 1, 2, 4, 7 };
bool is5inSet = numbers.Contains(5);
So che ci sono un sacco di risposte qui, ma qui è il mio prendere in materia, usata quotidianamente in SubSonic. si tratta di un metodo di estensione:
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));
}
e 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));
}
utilizzo:
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);
questo mi fa davvero sorridere ogni volta ho rivedere it :)
jim
[modifica] - originariamente provenienti da qui su SO, ma modificati per utilizzare params IQueryable e: 'Contains()' workaround using Linq to Entities?
+1 Davvero bello! – wasatz
o utilizzando System.Linq
...
(VB.NET)
Enumerable.Contains({1, 2, 4, 7}, value)
o
{1, 2, 4, 7}.Contains(value)
(C#)
Enumerable.Contains(new int[]{1, 2, 4, 7}, value);
o
new int[] {1, 2, 4, 7}.Contains(value);
Solo questo: '{1, 2, 4, 7}. Contiene (valore)'. – Neolisk
Ecco alcune semplici Linq con qualche pseudo codice. Non c'è bisogno di reinventare la ruota.
int[] values = new int[]{1, 2, 4, 7};
int target = 2;
bool contains = values.Any(v => v == target);
Oppure utilizzare .Contains
come alcuni hanno suggerito.
quale versione del framework .NET? –
Uso principalmente 3.5. Non sono sicuro se c'è qualcosa in 4.0 che rende più facile questo? –