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 может дать вам этот последний шаг (который я не очень хорошо знаю).