6

私は自分のシナリオをできる限り最善の方法で説明しようとします。データベースに次のテーブルがあります。

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

したがって、目標は、あるカテゴリに属する​​製品のリストを作成することであり、各カテゴリには、「PropertyValues」テーブルの値を持つ「n」個のプロパティを含めることができます。'categoryId'に基づいてデータを返すクエリがあるので、データベースから常に異なる結果を取得できます。

CPUカテゴリの場合:

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

HDDカテゴリの場合:

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

そのため、結果としてクエリのカテゴリに基づいて、常に異なる列番号と名前を取得できます。データベースアクセスには、結果を返すストアドプロシージャへの単純なADO.NET呼び出しを使用します。しかし、クエリ結果は本質的に動的であるため、このデータを読み取るための適切な方法がわかりません。

私はProductエンティティを作成しましたが、実際に作成する方法がわかりません:(エンティティを作成し、、、、、、、などを継承する他のProductエンティティを作成 できると思いましたが、これを終了できるので愚かだと思いますドメイン内の 200以上のエンティティ。 この状況で何をしますか?この動的プロパティの 読み方と配置場所? 更新-いくつかの解決策@millimooseの提案と@TimSchmelterのアイデアに 基づいています ProductCpuHddCameraPcCaseGraphicCardMobilePhoneGps








DictionaryDataTableオブジェクト私はいくつかの解決策に到達しました。
さて...これはうまくいきます。データを読み取って表示することができます。
しかし、私はまだ私よりも賢い人々からのアドバイスが必要です。私はこれをうまくやったのか、これをうまく処理するべきなのか、それともスパゲッティコードを作ったのか。だからここで私がしたこと:

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

2 に答える 2

2

あなたのオリジナルのアプローチ

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

かなり良いです。ただし、意図が明確になるように名前を付けたカスタムコレクションを使用します。


dynamicよりクールなC#4.0の機能を利用することもできますが、それがあなたの場合にどのようなメリットをもたらすかはわかりません。あなたは次のようなことをすることができます、

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

やや関連する質問:データリーダーを動的なクエリ結果に変換する方法

于 2015-08-01T11:23:23.570 に答える
1

製品と一連のカテゴリがあり、各カテゴリには多数のプロパティがあります。

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

製品のプロパティをリスト/辞書に保存できます

次に、製品にプロパティを追加するだけです

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

またはその名前/値の場合

Properties.Add(new ProductionProperty() { Name="Speed", Value="150MB/s"});
于 2013-03-04T21:47:50.950 に答える