以下代码生成两个项目。第一项包含Component
个对象的列表。第二个项目还包含Component
个对象的列表。在此示例中,第二个列表应为空,因为Component
列表没有DishID=10
。我该如何解决这个问题?
换句话说,result[1].components.Count
应为0。
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
List<Component> Component = new List<Component>();
List<Dish> Dish = new List<Dish>();
Dish.Add(new Dish { DishID = 9, CategoryID = 6, DishName = "Pork" });
Dish.Add(new Dish { DishID = 10, CategoryID = 6, DishName = "Beef" });
Component.Add(new Component { ComponentID = 1, DishID = 9, AmountID = "1", NameID = "1" });
List<Item> result = (from dishes in Dish
join components in Component on dishes.DishID equals components.DishID
into item
from p in item.DefaultIfEmpty()
select new { CategoryID = dishes.CategoryID, DishID = dishes.DishID, ComponentID = p != null ? p.ComponentID : default(int), DishName = dishes.DishName, AmountID = p != null ? p.AmountID : null, NameID = p != null ? p.NameID : null }).ToList().GroupBy(key => key.DishID)
.Select(g => new Item()
{
DishID = g.Key,
components = g.Select(t => new Component { AmountID = t.AmountID, ComponentID = t.ComponentID, DishID = t.DishID, NameID = t.NameID }).ToList()
})
.ToList();
}
}
public class Item
{
public int DishID { get; set; }
public List<Component> components { get; set; }
}
public partial class Component
{
public int ComponentID { get; set; }
public int DishID { get; set; }
public string AmountID { get; set; }
public string NameID { get; set; }
}
public partial class Dish
{
public int DishID { get; set; }
public int CategoryID { get; set; }
public string DishName { get; set; }
}
}
答案 0 :(得分:2)
如果ComponentId为空(在本例中为0
),则没有匹配项,因此在创建结果列表项时过滤空Component
个对象,在本例中使用.Where (x => x.ComponentID > 0)
在最后一个select语句之前:
List<Item> result = (from dishes in Dish
join components in Component on dishes.DishID equals components.DishID into item
from p in item.DefaultIfEmpty()
select new
{
CategoryID = dishes.CategoryID,
DishID = dishes.DishID,
ComponentID = p != null ? p.ComponentID : default(int),
DishName = dishes.DishName,
AmountID = p != null ? p.AmountID : null,
NameID = p != null ? p.NameID : null
})
.ToList()
.GroupBy(key => key.DishID)
.Select(g => new Item()
{
DishID = g.Key,
components = g
.Where (x => x.ComponentID > 0)
.Select(t => new Component
{
AmountID = t.AmountID,
ComponentID = t.ComponentID,
DishID = t.DishID,
NameID = t.NameID
})
.ToList()
})
.ToList();
现在结果包含两个项目,第一个包含DishId=9
,第二个列表(用于DishId=10
)为空。
如果我理解你的要求,我认为代码可以简化:
代码如下所示:
List<Item> result1 = new List<Item>();
Dish.ForEach(dish =>
{
var item = new Item
{
DishID = dish.DishID,
components = Component.Where (c => c.DishID == dish.DishID).ToList()
};
result1.Add(item);
});
输出与您的代码相同。
由于您正在制作LEFT JOIN
using LINQ(from p in item.DefaultIfEmpty()
),我假设您还想从结果中排除空项。这可以通过向第一个查询添加where
条件(where ((p != null) && (p.ComponentID > 0))
)来完成:
List<Item> result = (from dishes in Dish
join components in Component on dishes.DishID equals components.DishID into item
from p in item.DefaultIfEmpty()
where ((p != null) && (p.ComponentID > 0))
select new
{
CategoryID = dishes.CategoryID,
DishID = dishes.DishID,
ComponentID = p != null ? p.ComponentID : default(int),
DishName = dishes.DishName,
AmountID = p != null ? p.AmountID : null,
NameID = p != null ? p.NameID : null
})
.ToList()
.GroupBy(key => key.DishID)
.Select(g => new Item()
{
DishID = g.Key,
components = g.Select(t => new Component
{
AmountID = t.AmountID,
ComponentID = t.ComponentID,
DishID = t.DishID,
NameID = t.NameID
})
.ToList()
})
.ToList();
正如预期的那样,结果只包含Component
的{{1}}项。
答案 1 :(得分:1)
老实说,我不明白为什么你使用所有左连接,分组和中间投影(选择),而你可以通过这样的简单Group Join获得所需的结果:
var result = (
from d in Dish
join c in Component on d.DishID equals c.DishID into items
select new Item { DishID = d.DishID, components = items.ToList() }
).ToList();