2012-08-07 25 views
6

Estoy usando EF Code First (4.3.1) en un proyecto ASP.NET MVC 3 personal, con un modelo de dominio muy simple, y estoy casi en el punto donde EF generará el esquema DB de la manera que yo quiera. El modelo de dominio tiene dos clases: Painting y Gallery. Cada Painting pertenece a un solo Gallery, y el Gallery tiene dos propiedades virtuales que apuntan a Painting: Una para indicar cuál de las pinturas es su imagen de portada, y una para cuál de las pinturas es la imagen del Control deslizante que se muestra en la página de inicio.Código Entity Framework Primero - Nombre de Columna de Propiedad Virtual

Las clases son las siguientes. He eliminado algunas anotaciones y propiedades irrelevantes para que sea legible.

public class Gallery 
{ 
    public Gallery() 
    { 
     Paintings = new List<Painting>(); 
    } 

    [ScaffoldColumn(false)] 
    [Key] 
    public int GalleryId { get; set; } 

    public string Name { get; set; } 

    [ScaffoldColumn(false)] 
    [Column("LaCover")] 
    public Painting Cover { get; set; } 

    [ScaffoldColumn(false)] 
    [Column("ElSlider")] 
    public Painting Slider { get; set; } 

    [ScaffoldColumn(false)] 
    public virtual List<Painting> Paintings { get; set; } 
} 

y pintura:

public class Painting 
{ 
    [ScaffoldColumn(false)] 
    [Key] 
    public int PaintingId { get; set; } 

    public string Name { get; set; } 

    public int GalleryId { get; set; } 

    [Column("GalleryId")] 
    [ForeignKey("GalleryId")] 
    [InverseProperty("Paintings")] 
    public virtual Gallery Gallery { get; set; } 

    public string Filename { get; set; } 
} 

Genera un esquema db correcta para ambas clases y sus relaciones, el único pequeño problema que tengo es que no he encontrado una manera de controlar los nombres de columna da a las propiedades virtuales de Cover y Slider en la tabla Gallery.

Los llamará Cover_PaintingId y Slider_PaintingId.

Intenté utilizar el atributo [Column("columnNameHere")], pero eso no lo afecta en absoluto. Como en "Escribí una cierta palabra no relacionada y no apareció en el esquema".

Me gustaría llamarlo CoverPaintingId, sin el guión bajo.

Cualquier ayuda es muy apreciada. Gracias

Respuesta

6

El atributo ForeignKey le permite definir la propiedad que actuará como su clave externa si quiere que existe dentro de su modelo:

[ForeignKey("CoverPaintingId")] 
public virtual Painting Cover { get; set; } 
public int? CoverPaintingId { get; set; } 

Nota usted puede poner el atributo ya sea en la propiedad virtual en el extranjero clave: solo necesita especificar el nombre del "otro".

Sin embargo, ya que tendrá dos relaciones entre el mismo conjunto de entidades, no podrá hacer esto sin desactivar las eliminaciones en cascada en una o en ambas. Esto solo se puede hacer usando el Fluent Configuration API.

public class Gallery 
{ 
    public int GalleryId { get; set; } 

    [ForeignKey("CoverPaintingId")] 
    public virtual Painting Cover { get; set; } 
    public int? CoverPaintingId { get; set; } 

    [ForeignKey("SliderPaintingId")] 
    public virtual Painting Slider { get; set; } 
    public int? SliderPaintingId { get; set; } 

} 

public class Painting 
{ 
    public int PaintingId { get; set; } 
} 

public class MyContext : DbContext 
{ 
    public DbSet<Gallery> Galleries { get; set; } 
    public DbSet<Painting> Paintins { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Gallery>().HasOptional(g => g.Cover).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Gallery>().HasOptional(g => g.Slider).WithMany().WillCascadeOnDelete(false); 
    } 
} 

Si no desea que las propiedades de clave externa de existir en su modelo de código, también se puede configurar mediante el uso de estos .Map(...) antes de la. WillCascadeOnDelete(false) parte de la API en lugar de usar ForeignKey. Yo prefiero usar clave externa, pero así es como el código se vería si desea hacerlo de esta manera:

public class Gallery 
{ 
    public int GalleryId { get; set; } 
    public virtual Painting Cover { get; set; } 
    public virtual Painting Slider { get; set; } 
} 

public class Painting 
{ 
    public int PaintingId { get; set; } 
} 

public class MyContext : DbContext 
{ 
    public DbSet<Gallery> Galleries { get; set; } 
    public DbSet<Painting> Paintins { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Gallery>().HasOptional(g => g.Cover).WithMany().Map(m => m.MapKey("CoverPaintingId")).WillCascadeOnDelete(false); 
     modelBuilder.Entity<Gallery>().HasOptional(g => g.Slider).WithMany().Map(m => m.MapKey("SliderPaintingId")).WillCascadeOnDelete(false); 
    } 
} 
+0

Lo intenté también con Richard, pero recibí el siguiente error: Al introducir la restricción FOREIGN KEY 'FK_Galleries_Paintings_CoverPaintingId' en la tabla 'Galleries' puede provocar ciclos o múltiples rutas en cascada. Especifique ON DELETE NO ACTION o ON UPDATE NO ACTION, o modifique otras restricciones FOREIGN KEY. No se pudo crear una restricción. Ver errores previos. – GR7

+0

Ah sí, olvidé que obtendría eso con múltiples relaciones. Se actualizó la respuesta para explicar cómo evitar eso. – Richard

+0

Richard. Avancé un poco, gracias, pero ahora recibo el siguiente error: ForeignKeyAttribute en la propiedad 'Cover' en el tipo 'ap.Models.Gallery' no es válido. El nombre de la clave externa 'CoverPaintingId' no se encontró en el tipo dependiente 'ap.Models.Painting'. El valor Name debe ser una lista separada por comas de nombres de propiedades de claves foráneas. Y por lo que dice el error, entiendo que tendría que crear una propiedad CoverPaintingId en Painting? Eso no era lo que quería, ya que solo quiero nombrar la columna que ya se ha creado en la galería como "CoverPaintingId" en lugar de "Cover_PaintingId" – GR7

0

podría intentar usar la decoración [inverseproperty] para lograr esto.

+0

Clot, creo que es para cuando tienes relaciones invertidas y decirle a EF no crear relaciones dobles FK . De hecho, estoy usando eso, pero para la propiedad Pinturas en la clase Galería. InverseProperty no funcionaría para lo que quiero hacer.Necesito esas columnas en la Galería, solo quiero nombrarlas de manera diferente. – GR7

Cuestiones relacionadas