2

将表格数据中的重复列折叠到列表中的最优雅的方法是什么?

示例:我编写了一个 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 足够熟悉,怀疑它可以很好地折叠这些数据,但还不够熟悉,无法想到一个确切的方法。

4

3 回答 3

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 对元素进行分组;

于 2012-05-17T23:36:45.330 回答
1

您可以加载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>

于 2012-05-17T23:47:23.510 回答
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"
);
于 2012-05-17T23:35:02.030 回答