2013-03-04 18 views
6

Cercherò di spiegare il mio scenario nel miglior modo possibile. Ho le seguenti tabelle nel mio database:Come leggere le proprietà dinamiche dal database

Products{ProductId, CategoryId ...} 
Categories{CategoryId ...} 
CategoryProperties{CategoryPropertyId, CategoryId, Name ...} 
PropertyValues{ProductId, CategoryPropertyId, Value ...} 

Quindi l'obiettivo è quello di avere l'elenco dei prodotti che appartiene a una certa categoria e ogni categoria può avere 'n' numero di proprietà con valori nella tabella 'PropertyValues'. Ho una query che restituisce i dati in base a 'categoryId' in modo da poter sempre ottenere risultati diversi dal database:

Per la categoria CPU:

intel i7 | CPU | Model | Socket | L1 Cash | L2 Cahs | etc. 

Per la categoria HDD:

samsung F3 | HDD | Model | Speed | GB | etc. 

Quindi, in base alle categorie della mia query, posso sempre ottenere numeri di colonna e nomi diversi. Per l'accesso al database, utilizzo la semplice chiamata ADO.NET alla stored procedure che restituisce il risultato. Ma poiché il risultato della query è dinamico nella sua natura, non so quale sia un buon modo per leggere questi dati.

Ho fatto un'entità Product ma sono confuso come farlo davvero :( ho pensato che posso fare un'entità Product e fare altre entità che ereditareProduct come Cpu, Hdd, Camera, PcCase, GraphicCard, MobilePhone, Gps ecc

ma penso che è stupido perché posso concludere questo con 200 + entità nel dominio.

Cosa faresti in questa situazione?
Come leggere e dove inserire queste proprietà dinamiche ?

UPDATE - qualche soluzione

D'accordo sulla base di @millimoose suggerimento per Dictionary e @ Tim Schmelter idea di utilizzare DataTable oggetto sono venuto a qualche soluzione.
Ora ... questo funziona. I dati li leggono e posso visualizzarli.
Ma ho ancora bisogno di consigli da persone più intelligenti di me su am ho fatto questo buono o dovrei gestire meglio questo o mi sono fatto alcuni codice spageti. Quindi, ecco quello che ho fatto:

public class Product 
    { 
     public Product() 
     { 
      this.DynamicProperties = new List<Dictionary<string, string>>(); 
     } 

     public List<Dictionary<string, string>> DynamicProperties { get; set; } 

    } 
... 
List<Product> products = new List<Product>(); 
... 
using (SqlDataAdapter a = new SqlDataAdapter(cmd)) 
       { 
        DataTable t = new DataTable(); 
        a.Fill(t); 

        Product p = null; 

        foreach (DataRow row in t.Rows) 
        { 
         p = new Product(); 
         foreach (DataColumn col in t.Columns) 
         { 
          string property = col.ColumnName.ToString(); 
          string propertyValue = row[col.ColumnName].ToString(); 

          Dictionary<string, string> dictionary = new Dictionary<string, string>(); 

          dictionary.Add(property, propertyValue); 

          p.DynamicProperties.Add(dictionary); 
         } 

         products.Add(p); 
        } 
       } 
+1

C'è qualche motivo è necessario disporre di quelle proprietà disponibili nelle classi del modello, invece di avere un 'Product' avere un singolo' Dictionary '(o qualcosa del genere)? – millimoose

+0

L'approccio più semplice è usare 'DataTables'. Quindi è sufficiente una query sql e un 'SqlDataAdapter' per riempire la tabella. –

+0

@millimoose All'inizio pensavo a "dizionario". Ma non voglio sapere c'è qualche soluzione diversa per questo scenario. Oppure "Dizionario" è in realtà l'unica soluzione o la migliore. – 1110

risposta

1

hai un prodotto, un gruppo di categorie, e ogni categoria ha un sacco di proprietà.

class Product 
{ 
    public int Id { get; set; } 
    public Category Category { get; set; } 
    public List<ProductProperty> Properties { get; set; } 
} 

class Category 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

class ProductProperty 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

è possibile memorizzare le proprietà del prodotto in un elenco/dizionario

poi basta aggiungere proprietà al prodotto

Properties.Add(new ProductionProperty() { Name="intel i7"}); 

o se il suo nome/valore

Properties.Add(new ProductionProperty() { Name="Speed", Value="150MB/s"}); 
+0

Non riesco a gestirlo in questo modo. La proprietà 'Properties' dovrebbe essere dinamica, quindi non posso leggerla poiché non conosco il nome delle proprietà. – 1110

+0

è "dinamico" si popola ogni ProductProperty con qualsiasi cosa ritorna –

+0

come per l'aggiornamento –

0

Il tuo approccio originale

è abbastanza buono. Però userei una collezione personalizzata, con una denominazione migliore in modo che l'intento sia più chiaro.


Si potrebbe anche utilizzare C# 4.0 di dynamic caratteristica che più fresco, ma non sono sicuro di quello che dà beneficio nel tuo caso. Si potrebbe fare qualcosa di simile,

public class Product 
{ 
    public List<dynamic> DynamicProperties { get; set; } 
} 

... 

conn.Open(); 
using (var reader = cmd.ExecuteReader()) 
{ 
    var p = new Products(); 
    p.DynamicProperties = reader.AsDyamic().ToList(); 

    //or 

    foreach (var item in reader.AsDynamic()) 
     yield return item; 
} 

// carry this extension method around 
public static IEnumerable<dynamic> AsDynamic(this IDataReader reader) 
{ 
    var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); 
    foreach (IDataRecord record in reader as IEnumerable) 
    { 
     var expando = new ExpandoObject() as IDictionary<string, object>; 
     foreach (var name in names) 
      expando[name] = record[name]; 

     yield return expando; 
    } 
} 

domanda un po 'correlato: How to convert a data reader to dynamic query results

Problemi correlati