Tener un problema extraño con las tablas de mapeo con EF de código primero. Tengo una clase principal "Contrato" con una relación muchos-1 de otra clase "Proveedor". Surgió el requisito de almacenar una copia escaneada del contrato dentro de la entidad Contractual. Para evitar tener que consultar los bytes del documento cada vez, quiero almacenar esta propiedad en una tabla separada. Puedo hacer que EF almacene el ContractDocument en una tabla separada, pero por alguna razón, el FK a los proveedores termina en la tabla ContractDocument en lugar de en la tabla principal.

public class Contract
{
    public Guid Id {get;set;}
    ...
    public virtual ContractDocument Document {get;set;}
    public virtual Supplier Supplier {get;set;}
}

public class ContractDocument
{
    public string MimeType {get;set;}
    public byte[] Data {get;set;}
}

En DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Contract>()
                .Map(m => m.Properties(p => p.Document))
                .ToTable("ContractDocument");
    base.OnModelCreating(modelBuilder);
}

La tabla "ContractDocument" se crea con las propiedades correctas y guarda datos. Sin embargo, también contiene el campo FK "Supplier_Id". La tabla "Contrato" ya no contiene ningún campo FK.

3
GC. 24 feb. 2012 a las 20:11

1 respuesta

La mejor respuesta

No estoy seguro y no tengo VS para probar en este momento, pero creo que cuando divide una entidad en varias tablas, necesita mapear todos los campos, no solo los que son "inusuales".

Intente actualizar su mapeo a algo similar a estas líneas ...

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Contract>()
                .Map(m => {
                       m.Properties(p => 
                           new {
                              p.Id,
                              p.Document
                           });
                       m.ToTable("ContractDocument");
                    })
                .Map(m => {
                       m.Properties(p =>
                           new {
                              p.Id,
                              /* everything else NOT document */
                           });
                       m.ToTable("Contract");
                    });
    base.OnModelCreating(modelBuilder);
}

Corrección basada en esto

Editar Según su comentario, parece que necesita definir la relación, no la división de entidades. Tiene tablas y clases separadas, pero lo que falta es la relación entre ellas. Quizás intente algo como esto.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Contract>().ToTable("Contract");
    modelBuilder.Entity<ContractDocument>().ToTable("ContractDocument");
    modelBuilder.Entity<Contract>()
        .HasOptional(c => c.Document)
        .WithRequiredDependent();

2.ª edición Bien, para hacerlo como un tipo complejo, creo que necesitas la primera entidad que divide el material del mapa más una línea modelBuilder.ComplexType<ContractDocument>();.

2
Josh 29 feb. 2012 a las 18:31
Gracias por la respuesta, pero no importa. Las propiedades existentes ya están asignadas a las tablas correctas. Es el Supplier_Id generado el que termina en el lugar equivocado. Sospecho que esto es lo que estaba buscando, pero aún no lo he probado: weblogs.asp.net/manavi/archive/2011/04/24/…
 – 
GC.
28 feb. 2012 a las 17:50
Ah. Entendí mal la pregunta. Veo a lo que te refieres ahora. ¿La relación entre Contract y ContractDocument es de uno a uno o de uno a muchos?
 – 
Josh
28 feb. 2012 a las 21:14
Es uno a uno. Realmente quiero tratar la propiedad Document como un "tipo complejo" sin convertirla en una Entidad en DBContext, pero ponerla en una tabla separada por razones de rendimiento. Probaré tu sugerencia cuando tenga la oportunidad. Gracias.
 – 
GC.
29 feb. 2012 a las 14:19