嗨,Stack Overflow社区,我有一个存储过程(我不能修改,因此只能处理返回的数据),可以返回如下数据:
Group Code Value
===========================
GroupA 13 123
GroupA 17 456
GroupB 17 789
但是,我需要操纵此结果数据,使其看起来像这样:
Group Code Value
===========================
GroupA 13 123
GroupA 17 456
GroupB 17 789
GroupB 13 NULL
...以便我最终可以在 Code 列上使用LINQ的groupBy()获得以下结果:
Group Code Value
===========================
GroupA 17 456
GroupB 17 789
Group Code Value
===========================
GroupA 13 123
GroupB 13 NULL
因此,我们正在做一个笛卡尔积,该积具有 Group 列和 Code 列中的唯一值,并将此数据与我们的原始数据结合在一起。我可以像这样在SQL中相当简单地做到这一点:
DECLARE @TableData table (
[GroupName] nvarchar(200),
Code int,
Value int
);
DECLARE @CartesianProductTable table
(
GroupName nvarchar(200),
Code int
);
INSERT @TableData values
('GroupA', 13, 123),
('GroupB', 17, 456),
('GroupA', 17, 789)
INSERT
@CartesianProductTable
SELECT * FROM (
SELECT DISTINCT(GroupName) FROM @TableData
) T1, (
SELECT DISTINCT(Code) FROM @TableData
) T2
SELECT
c.GroupName,
c.Code,
t.Value
FROM
@TableData t RIGHT OUTER join
@CartesianProductTable c on t.GroupName = c.GroupName AND t.Code = c.Code
所以我的问题是,在我将数据作为C#中的DataTable检索后,如何在Linq中执行此操作?我以为我可以按 Code 列进行分组,例如:
var tableDataGrouped = dataTable.AsEnumerable()
.GroupBy(r => r.Field<int>("Code"))
.Select(x => x.CopyToDataTable());
但是它给了我这样的数据:
Group Code Value
===========================
GroupA 17 456
GroupB 17 789
Group Code Value
===========================
GroupA 13 123
当我需要返回的LINQ数据是这样的时候:
Group Code Value
===========================
GroupA 17 456
GroupB 17 789
Group Code Value
===========================
GroupA 13 123
GroupB 13 NULL
我对LINQ还是很陌生,因此您可以指出的任何提示都将对您有很大帮助。
答案 0 :(得分:0)
我认为这是一个棘手的问题,因为解决方案就是您最初的期望
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Group", typeof(string));
dt.Columns.Add("Code", typeof(int));
dt.Columns.Add("Value", typeof(int));
dt.Columns["Value"].AllowDBNull = true;
dt.Rows.Add(new object[] { "GroupA", 13,123});
dt.Rows.Add(new object[] { "GroupA", 17,456});
dt.Rows.Add(new object[] { "GroupB", 17,789});
List<int> codes = dt.AsEnumerable().Select(x => x.Field<int>("Code")).Distinct().ToList();
var groups = dt.AsEnumerable().GroupBy(x => x.Field<string>("Group")).ToList();
foreach (var group in groups)
{
foreach (int code in codes)
{
if (!group.Any(x => x.Field<int>("Code") == code))
{
dt.Rows.Add(new object[] { group.Key, code, DBNull.Value });
}
}
}
}
}
}