2016-07-31 79 views
1

复杂的Json我有两个表:创建使用实体框架C#asp.net

产品

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

图片

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

我想要得到的Json看起来像

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

所以我想获得所有图像o f使用实体框架的每个产品。我试着使用联接:

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

而我的Json

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

我的产品和图像模式:

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

您可以请您发布您的'产品'和'图像'的模型定义,以及您如何建模这两个实体之间的关系?因为如果这样做是正确的,那么,你不必执行连接,而只需要简单地获取'Product',然后序列化(可能使用'Json.NET')。 –

+0

已更新,请看看 –

+0

你可能想要做一个群组加入 – Rahul

回答

1

您可以明确地建模Product之间的one-to-many关系,Image如下所示:

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

而且在DbContext添加此配置,如下所示:

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

一旦关系模型正确,那么你可以使用:

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

,得到产物和简单序列化如下:

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

相关序列的那些期间将b加载的Images标记虚拟。您不需要执行和显式连接。这里的关键是你需要在处理DbContext实例之前序列化,否则延迟加载的功能可能不起作用,并且你可能会面临一些不希望的错误。

您也可以另外在Image中标记Product属性JsonIgnore以排除序列化和避免参考循环。

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

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

然后JSON你应该是以下几点:

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

我觉得太成为你的目的。

希望它有帮助。

+0

它给我一个错误'ObjectContext实例已经被处置,不能再被用于需要连接的操作。这件事情,如果我设置this.Configuration.LazyLoadingEnabled = false; –

+0

@IgorLevashov我认为你试图在处理'DbContext'实例后序列化。尝试在此之前序列化。我还更新了我的答案,并附上了一些可能对您有所帮助的额外提示。 –