Sebbene piuttosto potente, la libreria System.Linq.Dynamic presenta una sorprendente mancanza di documentazione, specialmente per quanto riguarda le convenzioni da seguire per le domande più complesse.
In una query a cui sto lavorando, contiene una chiamata FirstOrDefault
, ma non riesco a farlo funzionare.
Ecco l'espressione intera (non funzionale):
"Locations.FirstOrDefault(x => x.IsPrimaryLocation).Address1 as Address"
Posso scrivere questa espressione FirstOrDefault per lavorare con Dynamic Linq?
Qual è il modo corretto di scrivere questa espressione?
L'estensione della libreria dinamica è certamente un'opzione come già suggerito. un'alternativa dato il Where
in Dynamic Linq restituisce un Iqueryable
public static class DynamicQueryable {
public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values) { return (IQueryable<T>) Where((IQueryable) source, predicate, values); }
public static IQueryable Where(this IQueryable source, string predicate, params object[] values) {
utilizzando un oggetto dinamico per le "posizioni" del contesto o del repository.
Quindi utilizzare un dove che potrebbe contenere predicato stringa dinamico e seguire con firstOrDefault.
(cattura o prova per null non considerato)
DynamicLocations.Where(x => x.IsPrimaryLocation).FirstOrDefault( ).Address1 as Address;
o dinamico dove necessario
DynamicLocations.Where("IsPrimaryLocation",new string[]).FirstOrDefault( ).Address1 as Address;
Dettagli: è possibile esporre su un metodo in una classe di repository generica che si crea un'istanza come dinamica
public virtual IQueryable<TPoco> DynamicWhere(string predicate, params object[] values) {
return AllQ().Where(predicate, values);
}
Esempio di istanza dinamica del repository generico
public class RepositoryFactory<TPoco> where TPoco : BaseObject,new() {
public IRepositoryBase<TPoco> GetRepository(DbContext context) {
// get the Pocotype for generic repository instantiation
var pocoTypes = new[] {typeof (TPoco)}; // but supports <T,U>
Type repBaseType = typeof (RepositoryBase<>);
IRepositoryBase<TPoco> repository = InstantiateRepository(context, repBaseType, pocoTypes);
return repository;
}
private IRepositoryBase<TPoco> InstantiateRepository(DbContext context, Type repType, params Type[] args) {
Type repGenericType = repType.MakeGenericType(args);
object repInstance = Activator.CreateInstance(repGenericType, context);
return (IRepositoryBase<TPoco>)repInstance;
}
}