私はWPFでアプリケーションを書いています。Entity Framework 5 を使用していますが、次のような場合の対処方法についてアドバイスをいただけないでしょうか。
私は基本的に3つのテーブルしか持っていません:
アイテム {ID、名前}
属性 {ID、名前、タイプ}
AttributeValue {アイテムID、属性ID、値}
クライアントは自分のアイテムに属性を追加したいと考えており、これは非常にうまく機能しているようです。これで、属性を追加して、それらに値をアイテムに割り当てることができます。最初の質問: これは良いデザインだと思いますか?
問題は、アイテムを WPF DataGrid に表示し、すべての属性を列として表示する方法です。これは私たちが今持っているものです:
プログラムで列を生成します。
foreach (var attribute in db.Attributes)
{
datagrid.Columns.Add(new DataGridTextColumn
{
Header = attribute.Name,
Binding = new Binding { Path = new PropertyPath(string.Format("[{0}]", attribute.ID)) }
});
}
これはうまくいきます。ここでの問題は、Items-Class でインデクサーを実装する方法です。大量のデータ (20.000 アイテム、400 属性、すべてのアイテムに 100 の値がある) で非常に遅くなるオプションが 1 つあります。
public AttributeValue this[int i]
{
get
{
return AttributeValues.FirstOrDefault(aa => aa.AttributID == i);
}
}
私が言ったように、これは機能しますが、遅くなります。常に属性値を照会する代わりに、次のように表示する前にすべてをキャッシュすることを考えました:
var items = db.Items.AsNoTracking().ToArray();
CachedValues.Values = new Dictionary<int, Dictionary<int, AttributeValue>>(items.Length);
foreach (var item in items)
{
var attributevalues = db.AttributeValue.AsNoTracking().Where(w => w.ArtikelID == item.ID).ToArray();
CachedValues.Values[item.ID] = new Dictionary<int, AttributeValue>(attributevalues.Length);
foreach (var value in attributevalues)
{
CachedValues.Values[item.ID][value.AttributeID] = value;
}
}
静的クラスをキャッシュとして使用します。
public static class CachedValues
{
public static Dictionary<int, Dictionary<int, ArtikelAttribut>> Values;
}
そして、Items-Class でキャッシュにアクセスできます。
public AttributeValue this[int i]
{
get
{
AttributeValue val = null;
CachedValues.Values[ID].TryGetValue(i, out val);
return val;
}
}
明らかに、キャッシュの初期化にはある程度の時間 (15 秒) がかかりますが、その後ははるかに高速です。データグリッドの属性で項目を並べ替えるのに 1 秒しかかかりません。他のアプローチでは、それは何年もかかりました。
解決策に満足していません。何か提案はありますか? どんな種類の批判も歓迎します (どちらも良い解決策ではないことはわかっています)。
ありがとう、
トーマス
編集
最初の質問をより明確にするために、小さな例を示します。
項目: Item1,Item2,Item3,... 属性: Width, Height, Speed, ... AttributeValues: (Item1, Width, 100), (Item1,Height,200), (Item2,Width,100), (Item3 , 高さ, 200), (Item3,Speed,40)
つまり、これは典型的な多対多の関係です。属性は 0-many アイテムに表示される場合があり、Item は 0-many 属性を持つ場合があります。