Entity Framework 4 POCO с словарем
У меня есть POCO (обычный объект CLR)
public Foo
{
public virtual int Id { get; set; }
public virtual Dictionary<string, string> Stuff { get; set; }
public virtual string More { get; set; }
}
Используя первый подход (т.е. пока у меня нет модели данных), как бы я обрабатывал постоянный материал (словарь)?
Ответы
Ответ 1
Это не настоящий ответ на вопрос, но поскольку других ответов нет, я поделюсь тем, что я сделал.
Я просто создал новый тип {Id, Code, Text}
и заменил мой словарь на список этого типа. Затем я делаю что-то подобное, чтобы получить ключи, значения или выполнить поиск:
List<string> texts = (from sv in q.SelectableValues select sv.Text).ToList();
List<string> codes = (from sv in q.SelectableValues select sv.Code).ToList();
string text = (from sv in q.SelectableValues where sv.Code == "MyKey" select sv.Text).First();
В моем случае количество записей в словаре, как правило, мало. Однако см. этот вопрос для соображений производительности, когда словарь/список большой.
Ответ 2
Похоже, что обобщенный, правильный способ сохранения словаря в базе данных будет таким, как он перечислялся, поскольку таблицы по сути являются наборами с свободной концепцией порядка - точно так же, как IEnumerable. То есть, словарь перечисляется как IEnumerator < KeyValuePair < TKey, TValue → , и поэтому таблица должна иметь 2 столбца:
Key
Value
Оттуда у вас есть существующие соглашения EF для сложных типов, где Key может фактически быть объектом со многими свойствами и значением. Например, словарь пользовательских объектов может выглядеть так:
Username (TKey)
Address1 (TValue)
Address2 (TValue)
К сожалению, этот обобщенный шаблон не встроен в EF; это должно быть предложено.
Вместо разработки определенного типа для вашего решения вы можете использовать обобщенный класс, который генерирует аннотированную версию Data KeyValuePair < > .
public class EFKeyValuePair<TKey, TValue>
{
[Key]
public TKey Key { get; set; }
public TValue Value { get; set; }
}
Я не уверен, как бы вы гарантировали, что имена таблиц будут выписаны логически и поддающимся проверке образом, но не наследуя этот класс и добавляя атрибут для каждого подкласса. Возможно, Fluent API может дать вам этот последний шаг (который я не очень хорошо знаю).