2010-05-31 15 views
12

Tengo un (Objeto Plain Old CLR) POCOEntity Framework 4 POCO con diccionario

public Foo 
{ 
    public virtual int Id { get; set; } 
    public virtual Dictionary<string, string> Stuff { get; set; } 
    public virtual string More { get; set; } 
} 

Utilizando el enfoque model first (es decir, no tengo un modelo de datos aún), ¿cómo puedo manejar la persistencia de la materia (Diccionario)?

Respuesta

7

Esta no es una respuesta verdadera a la pregunta, pero como no hay otras respuestas, compartiré lo que hice.

Simplemente creé un nuevo tipo {Id, Code, Text} y reemplacé mi diccionario con una lista de ese tipo. entonces que hago algo como esto para obtener las claves, valores, o realizar una búsqueda:

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(); 

En mi caso, el número de entradas en el diccionario tiende a ser pequeña. Sin embargo, vea this question para consideraciones de rendimiento cuando el diccionario/lista es grande.

7

Parece que la forma generalizada y correcta de conservar un diccionario en una base de datos sería la forma en que está enumerado, ya que las tablas son esencialmente conjuntos con un concepto de orden libre, como IEnumerable. Es decir, un diccionario se enumera como IEnumerator < KeyValuePair < TKey, TValue>>, por lo que la mesa debe tener 2 columnas:

Key 
Value 

Desde allí se puede tener las convenciones EF existentes de tipos complejos, en los que la clave puede realmente ser un objeto con muchas propiedades y valor también. Por ejemplo, un diccionario de objetos de usuario podría ser:

Username (TKey) 
Address1 (TValue) 
Address2 (TValue) 

Es desafortunado este patrón generalizado no está integrado en EF; debería ser propuesto.

En lugar de desarrollar un tipo específico para su solución, puede usar una clase generalizada que produzca una versión anotada de datos de KeyValuePair <>.

public class EFKeyValuePair<TKey, TValue> 
{ 
    [Key] 
    public TKey Key { get; set; } 
    public TValue Value { get; set; } 
} 

No estoy seguro de cómo le gustaría asegurarse de los nombres de las tablas serían escritos a cabo de una manera lógica y verificable sin embargo sin heredar esta clase y la adición de un atributo a cada subclase. Tal vez la API Fluent podría darte este último paso (con el que no estoy muy familiarizado).

Cuestiones relacionadas