es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Crear una relación opcional-opcional en EF6 con una clave primaria (PK) en lugar de una clave foránea (FK).

¿Es posible crear un mapeo que llene automáticamente mi propiedad de navegación, basándose en la clave primaria de la tabla? Esto significa que no quiero tener una clave externa en ninguna tabla. Sé que es posible cuando hay un mapeo de Opcional – > Requerido. AFAIK no se crea ninguna restricción en SQL Server, la relación se “simula” mediante EF6 en tiempo de ejecución.

Entonces, ese código _dbContext.Cars.Include(x => x.Driver).First(x => x.Id == 1); devolvería un automóvil con conductor si existe, o un conductor nulo si no existe.

class Car
{
    public int Id { get; set; }
    public virtual Driver Driver { get; set; }
}

class Driver
{
    public int Id { get; set; }
    public virtual Car Car { get; set; }
}

El siguiente mapeo quiere crear un DriverId en mi Car:

class CarMapping : EntityTypeConfiguration<car>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
    }
}

class DriverMapping : EntityTypeConfiguration<driver>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
        HasOptional(x => x.Car)
            .WithOptionalPrincipal(x => x.Driver);
    }
}

EDIT

Comprobé con el mapeo mencionado anteriormente “requerido”:

class CarMapping : EntityTypeConfiguration<car>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
    }
}

class DriverMapping : EntityTypeConfiguration<driver>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
        HasOptional(x => x.Car)
            .WithRequired(x => x.Driver);
    }
}

Y funciona. EF6 no realiza ninguna validación en inserciones ni eliminaciones… ¿Es esto un error? Bueno, al menos funciona para mi caso.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible crear un mapeo que llene automáticamente su propiedad de navegación basándose en la clave primaria de la tabla, sin tener una clave externa en ninguna tabla. Esto se puede lograr utilizando un mapeo “HasOptional” con el método “WithRequired”.

    En el escenario dado, la clase “Car” tiene una propiedad de navegación “Driver” y viceversa. Dado que la relación entre “Car” y “Driver” es una relación uno a uno, podemos utilizar el método “HasOptional” para configurar la relación.

    class CarMapping : EntityTypeConfiguration<car>
    {
        public CarMapping()
        {
            HasKey(x => x.Id);
            HasOptional(x => x.Driver)
                .WithRequired(x => x.Car);
        }
    }
    
    class DriverMapping : EntityTypeConfiguration<driver>
    {
        public DriverMapping()
        {
            HasKey(x => x.Id);
        }
    }
    

    El código anterior creará una clave externa “DriverId” en la tabla “Car”. También configurará la propiedad de navegación en la clase “Car” para que se llene automáticamente con la entidad “Driver” relacionada basándose en el valor de la clave externa “DriverId”.

    Usando el código “_dbContext.Cars.Include(x => x.Driver).First(x => x.Id == 1)”, puede recuperar un carro con su conductor relacionado si existe, o nulo si no existe.

    Vale la pena señalar que el mapeo “HasOptional” con “WithRequired” no crea ninguna restricción en SQL Server. La relación está “simulada” por EF6 en tiempo de ejecución.

    Otra cosa a tener en cuenta es que EF6 no realiza ninguna validación en las inserciones o eliminaciones al utilizar este tipo de mapeo. Por lo tanto, aunque funciona para este escenario, puede que no funcione para todos los escenarios.

Comments are closed.