2012-09-02 29 views
35

Tengo una tabla llamada Productos que obviamente contiene productos. Sin embargo, necesito crear productos relacionados. Entonces, lo que hice fue crear una tabla de unión llamada product_related que tiene dos PK. ProductID de la tabla Products e RelatedID también de la tabla Products.EntityFramework Misma tabla Muchos a muchos Relación

Ya uso EF y he configurado todo en otras tablas. ¿Cómo debo agregar esto correctamente para crear una relación con los productos como tales: product.Products.Add(product object here). Por supuesto, aquí product representan un objeto de producto que he obtenido de la base de datos usando db.Products.FirstOr....

¿Cómo debo hacer esto correctamente? ¿Muchos a muchos en la misma mesa?

Gracias.

+1

Por favor, no use un M2M en una sola mesa si esto va a ser un software de producción, puede funcionar y funciona, pero es tan doloroso mantenerlo, estoy trabajando ahora pero si no tiene una respuesta para cuando llegue a casa, le mostraré una solución adecuada a su pregunta. – Chazt3n

+0

¿Está preguntando cómo agregar a la tabla product_related utilizando entity framework? –

Respuesta

68

Con el fin de crear una relación de muchos a muchos con base de datos-Primera aproximación necesita configurar un esquema de base de datos que sigue ciertas reglas:

  • Crear una tabla Products con una columna ProductID como primaria clave
  • Crear una tabla ProductRelations con una columna ProductID y una columna RelatedID y marque ambas columnas como (clave compuesta) primaria clave
  • No agregue ninguna otra columna a la tabla ProductRelations. Las dos columnas clave deben ser las únicas columnas en la tabla de dejar EF reconoce esta tabla como una tabla de enlace para una relación muchos-a-muchos relación
  • Crear dos relaciones de clave externa entre las dos tablas:
    • El primera relación tiene la tabla Products como clave primaria de la tabla con la clave como primaria ProductID y la tabla de ProductRelations como-key-tabla externa con sólo el ProductID como clave
    • la segunda relación exterior también tiene la tabla Products como primaria -key-table con el.210 clave como primario y la tabla ProductRelations como clave de la tabla externa con sólo el RelatedID como clave externa
  • Habilitar eliminación en cascada para la primera de las dos relaciones. (No puede hacerlo por ambos. SQL Server no permitirá esto porque resultaría en cascada los caminos múltiples de borrar.)

Si genera un modelo de datos entidad de esas dos tablas ahora obtendrá solo una entidad, a saber, una entidad Product (o quizás Products si deshabilita la singularización). La tabla de enlace ProductRelations no estará expuesta como una entidad.

La entidad Product tendrá dos propiedades de navegación:

public EntityCollection<Product> Products { get { ... } set { ... } } 
public EntityCollection<Product> Products1 { get { ... } set { ... } } 

Estas colecciones de navegación son los dos extremos de la misma relación de muchos a muchos. (Si tenía dos tablas diferentes que deseaba vincular por una relación muchos a muchos, digamos tabla A y B, una colección de navegación (Bs) estaría en la entidad A y la otra (As) estaría en la entidad B. debido a que su relación es "auto-referencia" ambas propiedades de navegación están en la entidad Product)

el significado de las dos propiedades son:. Products son los productos relacionados con el producto dado, Products1 son los productos que se refieren al producto dado . Por ejemplo: si la relación significa que un producto necesita otros productos como partes para fabricar y usted tiene los productos "Notebook", "Processor", "Silicon chips", entonces el "Processor" es hecho de "Silicon chips" ("Fichas de silicio" es un elemento de la colección de la entidad del producto Processor) y es utilizado por un "Bloc de notas" ("Bloc de notas" es un elemento de la Products1 de la entidad del producto Processor). En lugar de Products y Products1, los nombres MadeOf y UsedBy serían más apropiados.

Puede eliminar de forma segura una de las colecciones del modelo generado si solo está interesado en un lado de la relación. Simplemente elimine, por ejemplo, Products1 en la superficie del diseñador del modelo. También puede cambiar el nombre de las propiedades. La relación seguirá siendo de muchos a muchos.

Editar

Como se pidió en un comentario el modelo y el mapeo con un Código-Primera aproximación sería:

Modelo:

public class Product 
{ 
    public int ProductID { get; set; } 

    public ICollection<Product> RelatedProducts { get; set; } 
} 

Mapping:

public class MyContext : DbContext 
{ 
    public DbSet<Product> Products { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Product>() 
      .HasMany(p => RelatedProducts) 
      .WithMany() 
      .Map(m => 
      { 
       m.MapLeftKey("ProductID"); 
       m.MapRightKey("RelatedID"); 
       m.ToTable("product_related"); 
      }); 
    } 
} 
+2

¿Qué tal con Code-First? ¿Cómo se especifica la relación (con Fluent API)? – drzaus

+2

@drzaus: ver mi edición. Antes tenía una respuesta como esta, pero luego la eliminé cuando noté que se le había preguntado a DB-First. Agarró el código ahora de la respuesta eliminada :) – Slauma

+1

exactamente lo que estaba buscando @Slauma – drzaus

-1

Permite tomar su ejemplo:

relacionados Cuadro

Related_id  PK 
    Related_name 
    Date 

Producto Tabla

Product_id  PK 
    Related_id  FK 
    Product_Name 
    Date 

cómo representar en EF

Modelo Relacionado Clase nombrados como RelatedModel

[Key] 
    public int Related_id { get; set; } 

    public string Related_name {get;set} 

    public Datetime Date{get;set;} 

Producto Clase Modelo nombrado como ProductModel

[Key] 
    public int Product_id { get; set; } 

    public string Product_name {get;set} 

    public string Related_id {get;set} 

    public Datetime Date{get;set;} 

    [ForeignKey("Related_id ")]  //We can also specify here Foreign key 
    public virtual RelatedModel Related { get; set; } 

De esta manera podemos crear relaciones entre dos mesa

Ahora En caso de muchos a muchos relación I me gustaría tomar otro ejemplo aquí

Supongamos que tengo una clase del modelo Enrollment.cs

public class Enrollment 
{ 
    public int EnrollmentID { get; set; } 
    public int CourseID { get; set; } 
    public int StudentID { get; set; } 
    public decimal? Grade { get; set; } 
    public virtual Course Course { get; set; } 
    public virtual Student Student { get; set; } 
} 

Aquí courseid y StudentId son las dos claves externas

ahora tengo otra clase Course.cs donde crearemos Muchos de Muchas relaciones.

public class Course 
{ 
    public int CourseID { get; set; } 
    public string Title { get; set; } 
    public int Credits { get; set; } 
    public virtual ICollection<Enrollment> Enrollments { get; set; } 
} 

Hope This will help !!!

+1

Su respuesta está realmente lejos de la pregunta. 1) Su primer ejemplo es uno-a-muchos, 2) el segundo es uno-a-muchos también (a pesar de que usted está diciendo que sería muchos-a-muchos). 3) Tus relaciones no están entre la misma mesa y 4) él no está usando Code-First como lo hacen tus ejemplos. – Slauma

Cuestiones relacionadas