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!

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top