Sintassi lambda in linq a db4o?
Domanda
So che è possibile quanto segue con linq2db4o
from Apple a in db
where a.Color.Equals(Colors.Green)
select a
Ciò di cui ho bisogno è qualcosa che mi permetta di creare la mia query in modo condizionale (come posso fare in altre varianti di linq)
public IEnumerable<Apple> SearchApples (AppleSearchbag bag){
var q = db.Apples;
if(bag.Color != null){
q = q.Where(a=>a.Color.Equals(bag.Color));
}
return q.AsEnumerable();
}
In una situazione del mondo reale la borsa di ricerca conterrà molte proprietà e costruire un gigantesco if-tree che cattura tutte le possibili combinazioni di proprietà compilate sarebbe opera di un pazzo.
È possibile prima chiamare
var q = (from Color c in db select c);
e quindi continua da lì. ma questo non è esattamente quello che sto cercando.
Dichiarazione di non responsabilità: quasi duplicato di la mia domanda di quasi 11 mesi fa.
Questo è un po 'più chiaro dato che ora capisco meglio la faccenda e spero che ora alcuni degli occhi di sviluppo di db4o possano cogliere questo aspetto:
Qualche suggerimento?
Soluzione
Sì, è sicuramente possibile comporre query LINQ ottimizzate utilizzando db4o. Concesso che db sia definito come segue:
IObjectContainer db;
Ecco la tua richiesta:
public IEnumerable<Apple> SearchApples (AppleSearchbag bag)
{
var query = db.Cast<Apple> ();
// query will be a Db4objects.Db4o.Linq.IDb4oLinqQuery<Apple>
if (bag.Color != null)
query = query.Where (a => a.Color == bag.Color);
return query;
}
In tal caso, la query verrà eseguita ogni volta che l'enumerabile restituito viene ripetuto.
Un'altra possibilità è quella di utilizzare il meccanismo IQueryable, che ha il vantaggio di essere meglio riconosciuto dagli sviluppatori:
public IQueryable<Apple> SearchApples (AppleSearchbag bag)
{
var query = db.AsQueryable<Apple> ();
// query will be a System.Linq.IQueryble<Apple>
if (bag.Color != null)
query = query.Where (a => a.Color == bag.Color);
return query;
}
In entrambi i casi, db4o proverà a dedurre una query ottimizzata dall'espressione lambda al momento dell'esecuzione e, se fallisce, tornerà a LINQ agli oggetti. Il primo ha il vantaggio di essere più diretto, evitando la query su LINQ alla trasformazione db4o.