我有这个对象结构
public class Product
{
public int Id {get;set;}
public string DisplayName{get;set;}
public Ingredient[] Ingredents{get;set;}
}
public class Ingredient
{
public int id{get;set;}
public string Name{get;set;}
}
我有以下结果集的数据表
Id | DisplayName | IngredientId | IngName
-------------+-------------------------+------------------------
1 | Prod1 | 1 | Ing1
1 | Prod1 | 2 | Ing2
1 | Prod1 | 3 | Ing3
2 | Prod2 | 1 | Ing1
2 | Prod2 | 2 | Ing2
3 | Prod3 | 1 | Ing1
3 | Prod3 | 2 | Ing2
我需要LINQ查询,它会给我产品列表如下: //描述结构的伪代码:
resultProductList =
{
new Product() { Id = 1
, DisplayName = "Prod1"
, Ingredients = {
new Ingredient{ Id = 1, Name = "Ing1" }
, new Ingredient{ Id = 2, Name = "Ing2" }
, new Ingredient{ Id = 3, Name = "Ing3" }
}
, new Product() { Id = 2
, DisplayName = "Prod2"
, Ingredients = {
new Ingredient{ Id = 1, Name = "Ing1" }
, new Ingredient{ Id = 2, Name = "Ing2" }
}
, new Product() { Id = 3
, DisplayName = "Prod3"
, Ingredients = {
new Ingredient{ Id = 1, Name = "Ing1" }
, new Ingredient{ Id = 2, Name = "Ing2" }
}
}
我提到this,但我无法得到解决方案。
List<Product> lstContracttype = dsGetProducts.Tables[0]
.AsEnumerable()
.Select(x => new Product
{
Id= Convert.ToInt32(x[0]),
DisplayName= Convert.ToString(x[1])
})
.GroupBy(y => y.id).ToList();
有人可以建议我如何编写LINQ查询以获得此结果?
更新 我又添加了一个子类并将其添加到主Product类中。见下文:
public class Product
{
public int Id {get;set;}
public string DisplayName{get;set;}
public Ingredient[] Ingredents{get;set;}
public Price MyPrice{get;set;}
}
public class Price
{
public int min {get;set;}
public int max {get;set;}
public int defaultPrice {get;set;}
}
我按如下方式修改了LINQ查询并获得了结果。
我的问题是在LINQ查询下面,我应该写.First<Price>
还是.FirstOrDefault<Price>
?
这是处理这种情况的正确方法还是有其他办法吗?
var lstProducts = dsGetProducts.Tables[0].AsEnumerable().Cast<DataRow>()
.GroupBy(r => new { Id = r["Id"],
DisplayName = r["DisplayName"],
priceMax = r["priceMax"],
priceMin = r["priceMin"],
priceDefault = r["priceDefault"]
})
.Select(g => new Product()
{
Id = (int)g.Key.Id,
DisplayName = (string)g.Key.DisplayName,
Ingredients = g.Select(r => new Ingredient()
{
id = (int)r["IngredientId"],
Name = (string)r["IngName"]
}).ToArray(),
MyPrice = g.Select(r => new Price()
{
min= (int)r["minPrice"],
max= (int)r["maxPrice"],
defaultPrice= (int)r["priceDefault"],
}).FirstOrDefault<Price>()
答案 0 :(得分:3)
您需要分组,然后项目:
dataTable.Rows.Cast<DataRow>()
.GroupBy(r => new { Id = r["Id"], DisplayName = r["DisplayName"] })
.Select(g => new Product()
{
Id = (int)g.Key.Id,
DisplayName = (string)g.Key.DisplayName,
Ingredients = g.Select(r => new Ingredient()
{
id = (int)r["IngredientId"],
Name = (string)r["IngName"]
}).ToArray()
});
您需要Cast<DataRow>
。自.NET 1.1以来,DataTable
已经存在,其中泛型不存在。因此,枚举器产生object
个实例。
考虑到评论,如果您使用Field<T>
中的System.Data.DataSetExtensions
扩展方法安装了.NET Framework 3.5,则可以使用另一个选项。请务必添加对程序集的引用:
dataTable.Rows.Cast<DataRow>()
.GroupBy(r => new { Id = r.Field<int>("Id"), DisplayName = r.Field<string>("DisplayName") })
.Select(g => new Product()
{
Id = g.Key.Id,
DisplayName = g.Key.DisplayName,
Ingredients = g.Select(r => new Ingredient()
{
id = r.Field<int>("IngredientId"),
Name = r.Field<string>("IngName")
}).ToArray()
});