Considerare un database con più tabelle create utilizzando prima il codice Entity Framework. Ogni tabella contiene un diverso tipo di oggetto, ma desidero creare una singola classe generica di query query per motivi di estensibilità. Per quanto riguarda un quadro di riferimento per questa classe ho una classe generica come così destinato a fungere da un wrapper per LINQ to SQL:Come creare un quesito generico di Linq C#?
public class DBQuerier<T>
where T : class
{
DbSet<T> relation;
public DBQuerier(DbSet<T> table)
{
relation = table;
}
public bool Exists(T toCheck);
public void Add(T toAdd);
public T (Get Dictionary<String, Object> fields);
public bool SubmitChanges();
public void Update(T toUpdate, Dictionary<String, Object> fields);
public void Delete(T toDelete);
}
Il mio problema arriva al primo ostacolo quando si cerca di verificare se esiste un record come non riesco a convertire tra il tipo generico T e un tipo di oggetto con cui sto provando a lavorare. Se uso di base Linq:
public bool Exists(T toCheck)
{
return (from row in relation
where row.Equals(toCheck)
select row).Any();
}
un'eccezione runtime si verifica come SQL non può funzionare con qualsiasi cosa, ma i tipi primitivi, anche se a implementare IComparable
e designare i miei Equals che confronta un singolo campo. Espressioni lambda sembrano avvicinarsi, ma poi ho ottenere problemi di nuovo con SQL non essere in grado di gestire più di tipi primitivi anche se la mia comprensione è che Expression.Equal
costretta a utilizzare la classe funzione di paragonabile:
public bool Exists(T toCheck)
{
ParameterExpression T1 = Expression.Parameter(typeof(myType), "T1");
ParameterExpression T2 = Expression.Parameter(typeof(myType), "T2");
BinaryExpression compare = Expression.Equal(T1, T2);
Func<T, T, bool> checker =
Expression.Lambda<Func<T, T, bool>>
(compare, new ParameterExpression[] { T1, T2 }).Compile();
return relation.Where(r => checker.Invoke(r, toCheck)).Any();
}
L'espressione l'albero è stato progettato in mente in modo che in seguito potessi aggiungere un'istruzione switch per costruire la query in base al tipo che stavo cercando di guardare. La mia domanda è: c'è un modo molto più semplice/migliore per farlo (o correggere quello che ho provato finora) visto che le uniche altre opzioni che posso vedere sono scrivere una classe per ogni tabella (non così facile da estendere) o controlla ogni lato di applicazione del record (potenzialmente terribilmente lento se devi trasferire l'intero database!)? Mi scuso se ho commesso errori così basilari in quanto non ho lavorato molto per molto tempo, grazie in anticipo!
Nota il metodo 'Exists' è solo un rinominato metodo' Contains' senza un'implementazione valida. – Servy
Se si dispone di una colonna della chiave primaria, è sempre possibile utilizzare il metodo 'relation.Find (Id)' per verificare se esiste. – Nilesh