将表格数据中的重复列折叠到列表中的最优雅方法是什么?
示例:我编写了一个SQL查询,该查询返回包含重复数据的行,但单个区分列除外:
FIRST LAST AGE CAR
Charles Burns 32 Accord
Charles Burns 32 Buick
Charles Burns 32 Lexus
Anders Hejlsberg 51 Porsche
Anders Hejlsberg 51 Ferrari
Anders Hejlsberg 51 Bugatti
Anders Hejlsberg 51 Pinto
我使用以下内容读取这些内容,然后将它们放入CarInfo对象中:
while(reader.Read()) {
first = reader["first"]
last = reader["last"]
//...
}
var myData = new CarInfo(first, last, ...);
该对象如下:
// CarInfo: Need 7 total instances with example data
string first { get; private set; }
string last { get; private set; }
int age { get; private set; }
string car { get; private set; }
我希望它看起来像:
// CarInfo: Need only 2 instances with example data;
string first { get; private set; }
string last { get; private set; }
int age { get; private set; }
List<string> cars { get; private set; }
我当然可以手动执行此操作,例如选择形成唯一ID的列并检查它们是否已经在我的列表(或字典或其他)中,但这看起来非常费力。 我对LINQ非常熟悉,怀疑它可以很好地破坏这些数据,但还不够熟悉,无法想到一个确切的方法。
答案 0 :(得分:1)
您是否尝试过Enumerable.GroupBy函数?这是你在寻找什么?
class A
{
public string a;
public string b;
public A(string x, string y)
{
a = x;
b = y;
}
}
static void Main(string[] args)
{
A[] tab = { new A("1", "1"), new A("2", "0"), new A("3", "1"), new A("4", "0"), new A("5", "1") };
var g = tab.GroupBy(x => x.b);
foreach (var x in g)
{
foreach (var y in x)
{
Console.WriteLine(y.a + "/" + y.b);
}
Console.WriteLine("----");
}
Console.ReadKey();
}
本守则返回:
{1,1}
{3,1}
{5,1}
--------
{2,0}
{4,0}
按字段b;
对元素进行分组答案 1 :(得分:1)
您可以load a DataTable
并使用LINQ-To-DataSet:
List<CarInfo> cars =
(from cRow in tblCars.AsEnumerable()
group cRow by new
{
first = cRow.Field<String>("first"),
last = cRow.Field<String>("last"),
age = cRow.Field<int>("age")
}into CarGroup
select new CarInfo()
{
first = CarGroup.Key.first,
last = CarGroup.Key.last,
age = CarGroup.Key.age ,
cars = CarGroup.Select(cRow => cRow.Field<String>("Car")).ToList()
}).ToList();
以匿名类型上面的组,其中三个字段为关键字。然后使用这些字段初始化CarInfo
个实例,并使用每个组中包含所有汽车的List<String>
属性进行初始化。
答案 2 :(得分:0)
我昨天刚刚遇到这个问题,但我正在使用Dapper,这是SO使用的漂亮的对象映射器。它使用“拆分”方法,您必须指定要将父列与子列分隔的列或列列表:
List<CarInfo> parent = new List<CarInfo>();
CarInfo current = null;
var q = _conn.Query<CarInfo, string, CarInfo>(sql
, (p, c0) =>
{
if (current == null || current.Id != p.Id)
{
current = p;
}
current.Cars.Add(c0);
parents.Add(current);
return current;
}
, splitOn: "CAR"
);