2011-11-30 22 views
8

Al crear clases POCO que contienen colecciones de tipos primitivos y persisten en EF Code First, el mejor consejo que he encontrado hasta ahora es crear una nueva clase que tenga una ID más la tipo primitivo:Entity Framework Code First y colecciones de tipos primitivos

Entity Framework and Models with Simple Arrays

Si ahora tengo varias clases que requieren propiedades de tipo ObservableCollection<string> y reemplazarlos con ObservableCollection<EntityString> (donde EntityString es un tipo personalizado con un ID y una propiedad de cadena), que terminan con una tabla EntityString que tiene varias columnas de clave externa, una para cada propiedad del tipo ObservableCollection<EntityString> en todos los tipos de concreto con tales propiedades.

Esto conduce a una hinchazón de columnas de clave foránea en su mayoría nulas en la tabla EntityString.

Un enfoque sería crear una subclase de EntityString y utilizar el modelo Table per Type para esas subclases. Sin embargo, eso requiere hacer cambios incómodos en el modelo de objetos simplemente para acomodar Entity Framework.

Preguntas:

  • es escribir la encapsulación la mejor manera de manejar Collection<PrimitiveType>?
  • En caso afirmativo, ¿cuáles son las ventajas y desventajas de permitir columnas múltiples (muchas) claves externas frente a la creación de tablas personalizadas por tipo (a cambio de un modelo incómodo)?

Respuesta

5

Promover el tipo simple a entidad es una opción. Si desea usar esa nueva entidad de tipo primitivo en más relaciones, es mejor eliminar por completo las propiedades de navegación de esa entidad y usar asociación independiente (sin propiedades FK).

public class StringEntity 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
} 

y mapeo:

modelBuilder.Entity<Foo1>().HasMany(f => f.Strings).WithOptional(); 
modelBuilder.Entity<Foo2>().HasMany(f => f.Strings).WithOptional(); 

En la base de datos obtendrá nueva FK anulable por director relacionados - no hay manera de evitarlo, excepto crear la clase especial StringEntity por director (no usar herencia para eso porque afecta el rendimiento).

hay una alternativa:

public class StringEntity 
{ 
    public int Id { get; set; } 
    public List<string> Strings { get; private set; } 

    public string Text 
    { 
     get 
     { 
      return String.Join(";", Strings); 
     } 

     set 
     { 
      Strings = value.Split(";").ToList(); 
     } 
    } 
} 

En este caso no es necesario tipo de entidad relacionada (y tabla adicional), sino que su entidad está contaminada con propiedad adicional Text que es sólo para la persistencia.

+1

Esta solución supone que un ';' (o cualquier otro carácter mágico seleccionado) no es una entrada válida para la cadena base, ¿correcto? –

+0

¿Es posible expresar la configuración fluida 'WithOptional' con atributos de clase? Entiendo que son alternativas entre sí, pero hasta el momento no he encontrado documentación completa sobre el tema. –

+0

Si la asignación predeterminada no hace que la relación sea opcional, no puede cambiarla con la anotación de datos. La anotación de datos se debe colocar en alguna propiedad, pero en este caso no hay ninguna propiedad en la entidad dependiente para usar. –

Cuestiones relacionadas