2013-03-04 38 views
6

Bu senaryoyu en iyi şekilde açıklamaya çalışacağım. Benim veritabanında aşağıdaki tablolar vardır: Veritabanından dinamik özellikler nasıl okunmalı

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

Yani amaç bazı kategoriye ait ve her kategori 'propertyvalues' tablosundaki değerlerle özelliklerinin 'n' sayıda olabilir hangi ürünlerin listesini sahip olmaktır. İşlemci kategori için

: HDD kategori için

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

:

samsung F3 | HDD | Model | Speed | GB | etc. 
Ben o yüzden hep veritabanından farklı sonuçlar elde edebilirsiniz 'KategoriNo' dayalı verileri döndüren bir sorgu var

Bu yüzden sorgularımdaki kategorilere dayanarak, her zaman farklı sütun numaraları ve isimleri alabilirim. Veritabanı erişimi için, sonuç veren saklı prosedüre basit ADO.NET çağrısı kullanıyorum. Ancak, sorgu sonucu doğası gereği dinamik olduğundan, bu verileri okumak için iyi bir yol olduğunu bilmiyorum.

Ben Product varlık ama ben gerçekten :( Ben Product varlık yapmak ve hangi devralır diğer varlıkları yapabilirsiniz düşünce nasıl karıştı yapılanProductCpu gibi Hdd, Camera, PcCase, GraphicCard, MobilePhone, Gps vb

ama sanırım ben 200+ varlıkları etki ile bu bitirebilirsiniz çünkü aptal olduğunu.

Bu durumda ne yaparsınız?
Okumak ve nereye yerleştirmek için bu bir dinamik özellikleri?

GÜNCELLEME - bazı çözüm

dayalı Pekala bazı çözüm geldi DataTable nesneyi kullanmak Dictionary ve @Tim SCHMELTER fikir için öneri @millimoose.
Şimdi, bu işler veriyi okuyor ve görüntüleyebiliyorum.
Ama yine de daha akıllı kişilerden tavsiye gerekiyor Ben bu iyi yaptım mı yoksa daha iyi idare mi yoksa spageti kodu yaptım. Yani burada ne yaptım :

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

: Sen,

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; } } 

Biraz ilgili soru gibi bir şey yapabileceğini '(ya da bunun gibi bir şey)? – millimoose

+0

En kolay yaklaşım 'DataTables 'kullanmaktır. Ardından, tabloyu doldurmak için bir sql-query ve bir 'SqlDataAdapter' gereklidir. –

+0

@millimoose Önce 'Sözlük' hakkında düşündüm. Ama bilmiyorum, bu senaryo için farklı bir çözüm var. Veya 'Sözlük' aslında tek veya en iyi çözümdür. – 1110

cevap

1

Bir ürünü, kategoriler bir grup var ve her kategori özelliklerinin bir grup vardır.

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; } 
} 

size sadece ürüne özelliklerini eklemek sonra bir liste/sözlükteki

ürün özelliklerini depolayabilir

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

veya eğer

Adından/değer

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

Böyle halledemem. 'Properties' özelliği dinamik olmalı, çünkü özelliklerin adını bilmediğim için okuyamıyorum. – 1110

+0

"dinamik", her bir ProductProperty ürününü, her güncelleme ile birlikte –

+0

güncellemesine göre doldurursunuz –

0

Orijinal yaklaşımınız

oldukça iyidir. Özel bir koleksiyon kullanmalıyım, ancak daha iyi adlandırma ile amaç daha nettir.


Ayrıca C# 4.0'ın dynamic özelliğini serin daha kullanmak olabilir, ama senin durumunda verir yarar emin değilim. Tek bir `Sözlüğü var sadece` Product` kalmadan, kendi modeli sınıflarında mevcut bu özellikleri olması gerekir bir sebebi var mı How to convert a data reader to dynamic query results