我有以下课程:
public class Order
{
public Order()
{
Items = new ObservableCollection<OrderItem>();
}
public string Code { get; set; }
public ICollection<OrderItem> Items { get; set; }
}
public class OrderItem
{
public OrderItem()
{
SubItems = new ObservableCollection<SubItem>();
}
public decimal Quantity { get; set; }
public decimal Price { get; set; }
public ICollection<SubItem> SubItems { get; set; }
}
public class SubItem
{
public DateTime Date { get; set; }
public decimal Quantity { get; set; }
public string UserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在我遇到的问题是我想在数据网格中显示这些类的所有数据,例如.使用代码:
Order order = new Order();
order.Code = "123";
order.Items.Add(new OrderItem()
{
Price = 30,
Quantity = 3,
SubItems = new Collection<SubItem>()
{
new SubItem() { Date = DateTime.Now, Quantity = 1, UserName = "User1" },
new SubItem() { Date = DateTime.Now, Quantity = 2, UserName = "User2" }
}
});
order.Items.Add(new OrderItem()
{
Price = 500,
Quantity = 50,
SubItems = new Collection<SubItem>()
{
new SubItem() { Date = DateTime.Now, Quantity = 20, UserName = "User1" },
new SubItem() { Date = DateTime.Now, Quantity = 20, UserName = "User2" },
new SubItem() { Date = DateTime.Now, Quantity = 10, UserName = "User3" }
}
});
Run Code Online (Sandbox Code Playgroud)
我需要在DataGrid上显示如下内容:
| Order.Code | Item.Price | Item.Quantity | SubItem.Quantity | SubItem.UserName |
| 123 | 30 | 3 | 1 | User1 |
| 123 | 30 | 3 | 2 | User2 |
| 123 | 500 | 50 | 20 | User1 |
| 123 | 500 | 50 | 20 | User2 |
| 123 | 500 | 50 | 10 | User3 |
Run Code Online (Sandbox Code Playgroud)
看起来很简单,但我不能这样做.我能做的最好的是引用OrderItem
on,SubItem
所以我可以在列数据绑定上使用它,但只有当我有subItems时才能使用它(如果没有SubItems
,我仍然需要显示OrderItem
数据).所以基本上我需要显示我看到的确切的事情,如果我执行一个连接3个表的SQL SELECT.
任何linq魔法都可以做到这一点?
使用SelectMany方法展平:
var res = order.Items
.SelectMany(i => i.SubItems, (Item, Sub) => new { Item, Sub })
.Select(r => new { order.Code,
r.Item.Price,
ItemQuantity = r.Item.Quantity,
SubItemQuantity = r.Sub.Quantity,
r.Sub.UserName });
Run Code Online (Sandbox Code Playgroud)
如果SubItems
集合可能为空,则可以使用DefaultIfEmpty方法:
var res = order.Items
.SelectMany(i => i.SubItems.DefaultIfEmpty(), (Item, Sub) => new { Item, Sub })
.Select(r => new { order.Code,
r.Item.Price,
ItemQuantity = r.Item.Quantity,
SubItemQuantity = r.Sub == null ? null : (Decimal?) r.Sub.Quantity ,
UserName = r.Sub == null ? (string)null : r.Sub.UserName });
Run Code Online (Sandbox Code Playgroud)
尝试Ideone.
试试这个,就像一个联接:
var table = from item in order.Items
from subItem in item.SubItems
select new
{
OrderCode = order.Code,
ItemPrice = item.Price,
ItemQuantity = item.Quantity,
SubItemQuantity = subItem.Quantity,
SubItemUserName = subItem.UserName
};
Run Code Online (Sandbox Code Playgroud)
您可以根据需要将其扩展到多个订单:
var table = from order in orders
from item in order.Items
from subItem in item.SubItems
select new
{
OrderCode = order.Code,
ItemPrice = item.Price,
ItemQuantity = item.Quantity,
SubItemQuantity = subItem.Quantity,
SubItemUserName = subItem.UserName
};
Run Code Online (Sandbox Code Playgroud)
这是一个链接:http : //msdn.microsoft.com/zh-cn/library/bb383978.aspx (请参阅“ 子句中的化合物”)
如果集合可以为空,请使用DefaultIfEmpty(),例如:
var table = from order in orders
from item in order.Items.DefaultIfEmpty(new OrderItem())
from subItem in item.SubItems.DefaultIfEmpty(new SubItem())
select new
{
OrderCode = order.Code,
ItemPrice = item.Price,
ItemQuantity = item.Quantity,
SubItemQuantity = subItem.Quantity,
SubItemUserName = subItem.UserName
};
Run Code Online (Sandbox Code Playgroud)
如果不将参数传递给DefaultIfEmpty(),则“默认”项将为null,因此您必须处理该问题,例如:
var table = from order in orders
from item in order.Items.DefaultIfEmpty()
from subItem in (item != null ? item.SubItems : Enumerable.Empty<SubItem>()).DefaultIfEmpty()
select new
{
OrderCode = order.Code,
ItemPrice = item != null ? item.Price.ToString() : "n/a",
ItemQuantity = item != null ? item.Quantity.ToString() : "n/a",
SubItemQuantity = subItem != null ? subItem.Quantity.ToString() : "n/a",
SubItemUserName = subItem != null ? subItem.UserName : "n/a"
};
Run Code Online (Sandbox Code Playgroud)
另一种选择:
var table = from order in orders
from item in order.Items.DefaultIfEmpty()
from subItem in (item != null ? item.SubItems : Enumerable.Empty<SubItem>()).DefaultIfEmpty()
select new
{
OrderCode = order.Code,
ItemPrice = item != null ? item.Price : default(decimal?),
ItemQuantity = item != null ? item.Quantity : default(decimal?),
SubItemQuantity = subItem != null ? subItem.Quantity : default(decimal?),
SubItemUserName = subItem != null ? subItem.UserName : null
};
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7289 次 |
最近记录: |