Entity Framework Core - Related products of type product

asp.net-core ef-fluent-api entity-framework-core

Question

I'm using Entity Framework Core and Fluent API.

I'm trying to implement a relatedProducts array that is included in my product model like so:

{
    "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"
        }
    ]
}

I currently have this in my Context:

        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);

My Related Product class looks like this:

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; }
}

The trouble is my relatedProduct array is just coming back empty even though I've linked up the Ids in the db.

Any assistance on this would be awesome as i don't want to end up 'Bodging' it!

1
0
2/5/2019 11:42:16 AM

Popular Answer

You have to Include the related products (unless Lazy Loading is enabled) while you are querying. So you can make your query like as follows:

var product = _dbContext.Products.Include(p => p.RelatedProducts)
                                .ThenInclude(rp => rp.Related)
                                .FirstOrDefault(p => p.Id == productId);

Now your desired product will have its related products.

Better project your query as follows:

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);

Here product is anonymous type. If you want you can make it strongly typed by projecting the query to a ViewModel as follows:

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;}
}

Then in query:

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);
2
2/5/2019 12:55:48 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow