ef code first - reconoce - El esquema especificado no es válido. Errores: la relación ''Product_CreatedByUser'' no se cargó porque el tipo ''Usuario'' no está disponible
migraciones entity framework (1)
Tengo el siguiente código de los primeros modelos y trato de inicializar la base de datos, dándome la siguiente mención de error. Un usuario puede tener múltiples productos, por lo que existe una relación de uno a muchos entre el usuario y el producto.
Schema specified is not valid. Errors: The relationship ''Models.Product_CreatedByUser'' was not loaded because the type ''User'' is not available.
Estoy usando el primer enfoque de código, ¿alguien me puede ayudar con esto?
Usuario:
public class User
{
public long UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Producto:
public class Product
{
public long ProductId { get; set; }
public string ProductCode { get; set; }
public string Name { get; set; }
public DateTime CreatedDate { get; set; }
public long CreatedBy { get; set; }
public long ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
public bool IsDeleted { get; set; }
[ForeignKey("CreatedBy")]
public virtual User CreatedByUser { get; set; }
[ForeignKey("ModifiedBy")]
public virtual User ModifiedByUser { get; set; }
}
Según el modelo, el Product
tiene 2 relaciones FK de varios a uno para el User
- 1 a CreatedBy
y 1 a ModifiedBy
. Sin embargo, la clase de User
contiene una única colección de Products
, mientras que EF requiere una o ninguna propiedad de navegación correspondiente para cada relación. Además, no sabe a cuál de los FK actuales se le asignará esa colección, por lo que intenta silenciosamente crear una tercera relación :( Dado que la asignación predeterminada no funciona para tales escenarios, debe usar InverseProperty
o InverseProperty
API para especificar las asignaciones correctamente.
Por ejemplo, el mapeo bidireccional se puede especificar así:
public class User
{
public long UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[InverseProperty("CreatedByUser")]
public virtual ICollection<Product> CreatedProducts { get; set; }
[InverseProperty("ModifiedByUser")]
public virtual ICollection<Product> ModifiedProducts { get; set; }
}
Upate: mientras que lo anterior soluciona el problema del mapeo, introduce otro problema conocido como múltiples rutas en cascada , porque por las convenciones de EF predeterminadas, la eliminación en cascada está activada para las relaciones de uno a muchos. Como necesita una configuración fluida para desactivar la eliminación de cascada en una o ambas relaciones, será mejor que quite las anotaciones ForeignKey
e InverseProperty
y configure todo con fluidez:
modelBuilder.Entity<Product>()
.HasRequired(e => e.CreatedByUser)
.WithMany(e => e.CreatedProducts)
.HasForeignKey(e => e.CreatedBy)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Product>()
.HasRequired(e => e.ModifiedByUser)
.WithMany(e => e.ModifiedProducts)
.HasForeignKey(e => e.ModifiedBy)
.WillCascadeOnDelete(false);