È possibile restituire IEnumerable di oggetti anonimi da DataContext.ExecuteQuery?
-
21-08-2019 - |
Domanda
Sviluppo di un motore di reporting dove i rapporti sono basati su modelli.Ogni modello dispone di stringa di query SQL e di ogni report con valori specifici per i parametri di query SQL.Per eseguire il rendering di un report ho impostato i parametri e chiamata DataContext.ExecuteQuery il metodo per ottenere la lista dei record.Ma per catturare colonne restituite devo sapere i loro nomi e di avere una classe con proprietà corrispondenti.
È possibile in qualche modo per tornare IEnumerable di oggetti anonimi da DataContext.ExecuteQuery quindi determinare le loro proprietà utilizzando la Riflessione?
Ho bisogno di un LINQ equivalente per SqlDataReader.GetValues.
Grazie!
Soluzione
Fino a quando abbiamo il C# 4.0 con dinamica parola chiave possiamo usare questa soluzione (leggermente modificato il codice di un articolo L'esecuzione arbitraria di query in LINQ to SQL da Octavio Hernández Leal):
public static class DataContextExtension
{
public static IEnumerable<Dictionary<string, object>> ExecuteQuery(this DataContext dataContext, string query)
{
using (DbCommand command = dataContext.Connection.CreateCommand())
{
command.CommandText = query;
dataContext.Connection.Open();
using (DbDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
dictionary.Add(reader.GetName(i), reader.GetValue(i));
yield return dictionary;
}
}
}
}
}
Questo metodo di estensione restituisce IEnumerable del Dizionario<> gli oggetti in cui chiavi sono i nomi delle query colonne.
Altri suggerimenti
Sì, si può fare.Si prega di dare un'occhiata a questo snippet.
class Program {
static void Main(string[] args) {
var persons = new Person[]{
new Person{Age=22,Name="John Doe",Id=1},
new Person{Age=23,Name="Jack Smith", Id=2},
new Person{Age=34,Name="Sara Parker", Id=3}
};
var anonData = GetAnonTypes(persons);
foreach (var item in anonData as IEnumerable) {
//use reflection to access propties
}
}
static object GetAnonTypes(IEnumerable<Person> persons) {
var query=from p in persons select new{
Id=p.Id,
Name=p.Name
};
return query;
}
}
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
- Il compilatore non è in grado di aprire il vostro sql e determinare le proprietà che dovrebbe esistere.
- Dal momento che si desidera che il compilatore per farlo, devo concludere che tu non capisci anonimo di battitura.
Non utilizzare LinqToSql per questo.Basta usare il DataReader metodo.