Tengo las siguientes tablas en mi base de datos:
Product ResourceAssociation ------- ------------------ Name /-------> Id ResourceAssociation_Id ------/ SomePropertyEntonces Product tiene un ResourceAssociation_Id, que es un FK para la tabla ResourceAssociation.
Esta es una aplicación heredada que tenía un mapa de Entity Framework 6 que contenía este fragmento de código:
HasOptional(t => t.ResourceAssociation).WithOptionalDependent().WillCascadeOnDelete(true);Estoy buscando portar esto a EF Core. Parece que EF Core ya no tiene HasOptional. He intentado esto:
builder.HasOne(t => t.ResourceAssociation) .WithOne().HasForeignKey("ResourceAssociation_Id") .IsRequired(false) .OnDelete(DeleteBehavior.Cascade); También intenté reemplazar WithOne con WithMany . Pero no funciona.
Cuando intento crear un nuevo producto, sin una asociación de recursos (porque no es necesaria), EF Core aún me dice que mi ModelState no es válido porque la asociación de recursos es nula.
No puedo especificar la propiedad en WithOne (por ejemplo WithOne(x => x.Product) ) porque ResourceAssociation es una tabla que también se usará para otras tablas (por ejemplo, Brand también tiene una columna ResourceAssociation_Id que apunta a esa tabla).
¿Es posible este tipo de configuración en EF Core? ¿O tendré que agregar las diferentes propiedades de navegación a mi clase ResourceAssociation (es decir, Producto, Marca,...)?
En EF Core, HasOne / WithOne (incluso con propiedades de navegación) no son suficientes para determinar cuál es la principal y cuál es la entidad dependiente en la relación uno a uno (para uno a muchos, uno siempre es principal, muchos es el dependiente, y para muchos a muchos no hay principal/dependiente).
Por eso, el argumento de tipo genérico de HasForeignKey / HasPrincipalKey es necesario para determinar la entidad dependiente/principal respectivamente. En realidad, esto se explica en el tema Otros patrones de relación - Uno a uno de la documentación de EF Core:
Al configurar la relación con Fluent API, utiliza los métodos
HasOneyWithOne.Al configurar la clave externa, debe especificar el tipo de entidad dependiente; observe el parámetro genérico proporcionado a
HasForeignKeyen la lista a continuación. En una relación de uno a muchos, está claro que la entidad con la navegación de referencia es la dependiente y la que tiene la colección es la principal. Pero esto no es así en una relación uno a uno, de ahí la necesidad de definirla explícitamente.
Entonces, lo que necesita aquí es especificar Product como dependiente de la relación, junto con la propiedad FK/nombre de columna:
builder.HasOne(t => t.ResourceAssociation) .WithOne() // ok, no navigation .HasForeignKey<Product>("ResourceAssociation_Id") // FK name in the dependent // ^^^ the dependent entity of the relationship .IsRequired(false) .OnDelete(DeleteBehavior.Cascade);