2012-06-27 20 views
8

Al usar el Código de Entidad Framework Primero 4.3.1 es posible crear relaciones con una multiplicidad de 1-a-1. Es decir, una entidad en cada extremo de la relación.Código de Entity Framework Primera relación uno-a-uno requerida-requerida

Es posible configurar 1-a-1 relaciones de ser -requerido requerido o requerido opcional ^. Sin embargo, cuando cambio entre los dos, no veo ninguna diferencia en:

  • El esquema de la base de datos generado. Me estoy dirigiendo a SQL Server 2008.
  • El comportamiento en tiempo de ejecución de EF.

Como tal, yo soy capaz de crear un RequiredPrincipalAs registro sin la correspondiente RequiredDependentAs registro, a pesar de la relación que se está configurando como -necesaria requerida. Esto parece contradecir la documentación para HasRequired (...):

Configura una relación necesaria de este tipo de entidad. Las instancias del tipo de entidad no podrán guardarse en la base de datos a menos que se especifique esta relación. La clave externa en la base de datos no podrá contener nulos.

http://msdn.microsoft.com/en-us/library/gg671317

Los requerida requeridas- entidades relación:

public class RequiredPrincipalA 
{ 
    public int Id { get; set; } 
    public virtual RequiredDependentA DependentA { get; set; } 
} 

public class RequiredDependentA 
{ 
    public int Id { get; set; } 
    public virtual RequiredPrincipalA PrincipalA { get; set; } 
} 

Los entidades relación requeridos-opcionales:

public class RequiredPrincipalB 
{ 
    public int Id { get; set; } 
    public virtual OptionalDependentB DependentB { get; set; } 
} 

public class OptionalDependentB 
{ 
    public int Id { get; set; } 
    public virtual RequiredPrincipalB PrincipalB { get; set; } 
} 

El DbContext y modelo conf iguration:

public class AppContext : DbContext 
{ 
    public DbSet<RequiredPrincipalA> PrincipalAs { get; set; } 
    public DbSet<RequiredDependentA> DependentAs { get; set; } 

    public DbSet<RequiredPrincipalB> PrincipalBs { get; set; } 
    public DbSet<OptionalDependentB> DependentBs { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<RequiredPrincipalA>() 
      .HasRequired(o => o.DependentA) 
      .WithRequiredPrincipal(o => o.PrincipalA); 

     modelBuilder.Entity<RequiredPrincipalB>() 
      .HasOptional(o => o.DependentB) 
      .WithRequired(o => o.PrincipalB); 
    } 
} 

El código de prueba:

Database.SetInitializer(new DropCreateDatabaseAlways<AppContext>()); 

using (var ctx = new AppContext()) 
{ 
    ctx.Database.Initialize(force: false); 

    ctx.PrincipalAs.Add(new RequiredPrincipalA()); 
    ctx.PrincipalBs.Add(new RequiredPrincipalB()); 

    ctx.SaveChanges(); 
} 

Soy consciente de que podría añadir un atributo de datos[Obligatorio] a las propiedades de navegación de RequiredPrincipalA.DependentA y RequiredDependentA.PrincipalA . Esto provocaría que la validación EF evite el escenario anterior. Sin embargo, no quiero hacer esto porque también valida que la propiedad de navegación se rellene al actualizar una entidad existente. Esto significa que la aplicación debe prearchivar la entidad en el otro extremo de la relación para cada actualización.

¿Por qué no veo ninguna diferencia en el comportamiento de EF simplemente al cambiar una relación entre -necesaria requerida y requiere opcional?

^Tenga en cuenta que opcional-opcional también es compatible, pero esto no forma parte de mi pregunta. Existen diferencias obvias en el esquema de base de datos generado y el comportamiento en tiempo de ejecución cuando se configura una relación opcional-opcional.

Respuesta

13

No sé por qué required-required está permitido en este caso, pero no puede existir en la base de datos porque la relación se basa en las claves principales. Required-required significa que A no puede insertarse si B no existe y B no se puede insertar si A no existe la relación A => ni A ni B pueden insertarse.

La relación de la base de datos siempre tiene entidad principal y dependiente, el principal siempre puede existir sin dependiente.

Real requerido-requerido en EF solo se puede lograr cuando ambos A y B están mapeados en la misma tabla (table splitting) porque en tal caso ambos se insertan con un solo comando de inserción.

+0

Gracias por su respuesta. Sin duda, aclara el aspecto del esquema de la base de datos de mi pregunta. Sin embargo, estoy muy interesado en entender por qué no hay ningún cambio de comportamiento aparente en EF. –

+0

¿Podría ser que required-required está permitido porque EF puede aplicarlo en tiempo de ejecución aunque no sea posible hacer cumplir esta restricción en SQL? –

+0

Luke, el hecho de que no haya diferencia en el esquema al configurar r/r yr/o ahora se comprende gracias a la respuesta de Ladislav. El punto ahora es que r/r no parece ser aplicado en tiempo de ejecución por EF, a pesar de lo que dice la documentación. –

5

No es realmente una respuesta, pero tengo más que decir que cabrá en los comentarios. Pero ya sabes, escribo 900 libros de páginas ... es solo cómo lo hago. :)

Curiosamente, yo esperaría que la configuración fluida se comporte de la misma manera que la anotación de datos y estoy confundido de que no lo está haciendo. (He llamado a Rowan Miller con un enlace a este hilo para obtener sus comentarios.) Y el comportamiento que quiero decir es: validar la restricción durante SaveChanges.

En el lado de la base de datos, estoy con Ladislav.En el modelo, EF define el 1: 1 utilizando las claves de las entidades relacionadas. Pero en la base de datos, no puede tener FK en ambas tablas, por lo que solo la tabla dependiente de la base de datos requerirá la restricción de que PK se asigna a una PK existente en la tabla principal.

Y, por último, entiendo su razón para no querer que EF haga cumplir la relación si no va a tratar siempre con el gráfico completo. Creo que las relaciones 1: 1 son las más confusas de las asignaciones de relaciones EF y siempre me veo obligado a volver para recordar las reglas y cómo deberían funcionar las cosas.

Cuestiones relacionadas