Я пишу приложение в WPF. Я использую Entity Framework 5 и хотел бы узнать, можете ли вы дать мне совет, как справиться со следующей ситуацией.
У меня есть в основном только три таблицы:
Элемент {ID, имя}
Атрибут {ID, имя, тип}
AttributeValue {ItemID, AttributeID, Значение}
Наш клиент хочет добавить атрибуты к своим предметам, и это, кажется, работает достаточно хорошо. Теперь он может добавлять атрибуты и присваивать им значения своим предметам. Первый вопрос: Как вы думаете, это хороший дизайн?
Теперь вопрос заключается в том, как отображать элементы в 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 значений):
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, Элемент2, Элемент3,... Атрибуты: Ширина, Высота, Скорость, ... Значения атрибутов: (Элемент1, Ширина, 100), (Элемент1, Высота, 200), (Элемент2, Ширина, 100), (Элемент3 , Высота, 200), (Элемент3,Скорость,40)
Итак, это классическая связь «многие ко многим». Атрибут может появиться в 0-многих элементах, а элемент может иметь 0-много атрибутов.