1

I have two tables:

Products

ProductId | ProductName
__________|____________
       1  | iPhone5
       2  | iPhone6
       3  | iPhone6s

Images

Id |    ImagePath     | ProductId
___|__________________|___________
1  | /images/231.jpg  |    2
2  | /images/432.jpg  |    2
3  | /images/111.jpg  |    1 

I want get Json looks like

{  
   "id":"2",
   "ProductName":"iPhone6"
},
"Images":[  
   {  
      "Id":"1",
      "ImagePath":"/images/231.jpg"
   },
   {  
      "Id":"2",
      "ImagePath":"/images/432.jpg"
   }
]

So I want to get all images of each Product using Entity Framework. I tried using join:

 var ads = db.Products.
      Join(db.Images, 
           x=>x.ProductId,
           cm=>cm.ProductId,
           (x ,cm) => new {
            Ads = x, 
            Images = cm
      }).
      Select(d => new {
            d.Ads.AdId,
            d.Images.ImagePath,
       }).
      Where(x => x.ProductId== 2).
      ToList();

And my Json

[
    {
        "AdId":2,
        "ImagePath":"/images/231.jpg"
    },
    {
        "AdId":2,
        "ImagePath":"/images/432.jpg"
    }
]

My Product and Image models:

public class Product{

    public int ProductId { get; set; }
    public string ProductName { get; set; }

    public virtual ICollection<Image> Images { get; set; }
}

public class Image{

    public int ImageId { get; set; }
    public string ImagePath { get; set; }
    public int ProductId { get; set; }

    public virtual Product Product { get; set; }
}
3
  • Can you please post your model definition for Product, and Image, along with how you are modelling the relationship between these 2 entities? Because if that is done correctly, then, you don't have to perform the join, and rather need to simply grab a Product, and serialize that (maybe using Json.NET). Commented Jul 31, 2016 at 20:09
  • updated, take a look please Commented Jul 31, 2016 at 20:15
  • You rather might want to do a group join Commented Jul 31, 2016 at 20:15

1 Answer 1

1

You may explicitly model the one-to-many relationship between the Product, and Image like following:

public class ProductConfig : EntityTypeConfiguration<Product>
{
    public ProductConfig()
    {
        HasMany(p => p.Images).WithRequired(i => i.Product).HasForeignKey(i => i.ProductId);
    }
}

And add this configuration in the DbContext, as follows:

public class MyDbContext:DbContext
{
    ...
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ProductConfig());            
    }
}

Once the relationship is modeled correctly then you can use:

var prod = myDbContext.Products.Find(2);

OR

var prod = myDbContext.Products.SingleOrDefault(p => p.ProductId == 2);

OR

var prod = myDbContext.Products.Where(p => p.Id == 2);

to get the product and simply serialize that as follows:

var iPhone6Json = JsonConvert.SerializeObject(iPhone6, Formatting.Indented);

The Images associated will b loaded during serialization as those are marked virtual. You don't need to perform and explicit join. The key here is that you need to serialize before disposing the DbContext instance, otherwise the feature of lazy loading may not work, and you may face some undesired error.

You may also additionally mark the Product property in Image as JsonIgnore to exclude that from serialization and avoid reference loop.

[JsonIgnore]
public int ProductId { get; set; }

[JsonIgnore]
public Product Product { get; set; }

Then the JSON you should have is following:

{  
    "id":"2",
    "ProductName":"iPhone6",
    "Images":[  
       {  
          "Id":"1",
          "ImagePath":"/images/231.jpg"
       },
       {  
          "Id":"2",
          "ImagePath":"/images/432.jpg"
       }
    ]
}

I think that too serves your purpose.

Hope it helps.

Sign up to request clarification or add additional context in comments.

2 Comments

It gives me an error 'The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.' This thing works if I set this.Configuration.LazyLoadingEnabled = false;
@IgorLevashov I think you are trying to serialize after disposing the DbContext instance. Try to serialize before that. I have also updated my answer with few additional pointers that might be helpful for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.