Estoy usando Entity Framework Core y Fluent API.
Estoy tratando de implementar una matriz de Productos relacionados que se incluye en mi modelo de producto así:
{
"id": 13
"name": "something",
"heading": "something else",
"summary": "please put me out my misery!"
"relatedProducts": [
{
"name": "something related",
"heading": "something else related",
"summary": "something in summary"
},
{
"name": "something related",
"heading": "something else related",
"summary": "something in summary"
}
]
}
Actualmente tengo esto en mi contexto:
modelBuilder.Entity<RelatedProduct>()
.HasKey(r => new { r.ProductId, r.RelatedId });
modelBuilder.Entity<RelatedProduct>()
.HasOne(p => p.Product)
.WithMany(r => r.RelatedProducts)
.HasForeignKey(p => p.ProductId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<RelatedProduct>()
.HasOne(p => p.Related)
.WithMany(r => r.ProductsRelated)
.HasForeignKey(p => p.RelatedId)
.OnDelete(DeleteBehavior.Restrict);
Mi clase de productos relacionados se ve así:
public class RelatedProduct
{
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public int RelatedId { get; set; }
public virtual Product Related { get; set; }
}
El problema es que mi matriz de productos relacionados está volviendo vacía, aunque he vinculado los identificadores en la base de datos.
Cualquier ayuda en esto sería increíble ya que no quiero terminar 'Bodging'!
Debe Include
los productos relacionados (a menos que la Carga diferida esté habilitada) mientras realiza la consulta. Para que pueda realizar su consulta de la siguiente manera:
var product = _dbContext.Products.Include(p => p.RelatedProducts)
.ThenInclude(rp => rp.Related)
.FirstOrDefault(p => p.Id == productId);
Ahora su producto deseado tendrá sus productos relacionados.
Mejor proyectar su consulta de la siguiente manera:
var product = _dbContext.Products.Select(p => new
{
p.Id,
p.Name,
p.Heading,
p.Summary
RelatedProducts = u.RelatedProducts.Select(rp => rp.Related).ToList()
}).FirstOrDefault(p => p.Id == productId);
Aquí el product
es de tipo anónimo. Si lo desea, puede hacerlo con ViewModel
fuerza proyectando la consulta en un ViewModel
siguiente manera:
public class ProductDetailsViewModel
{
public int Id {get; set;}
public string Name {get; set;}
public string Heading {get; set;}
public string Summary {get; set;}
public List<Product> RelatedProducts {get; set;}
}
Luego en la consulta:
var product = _dbContext.Products.Select(p => new ProductDetailsViewModel
{
Id =p.Id,
Name = p.Name,
Heading = p.Heading,
Summary = p.Summary
RelatedProducts = p.RelatedProducts.Select(rp => rp.Related).ToList()
}).FirstOrDefault(p => p.Id == productId);