[英]Group by linq for nested objects
我正在通过linq语句进行分组,其中我将单个数据列表转换为带有嵌套列表的列表。 到目前为止,这是我的代码:
[TestMethod]
public void LinqTestNestedSelect2()
{
// initialization
List<combi> listToLinq = new List<combi>() {
new combi{ id = 1, desc = "a", name = "A", count = 1 },
new combi{ id = 1, desc = "b", name = "A", count = 2 },
new combi{ id = 2, desc = "c", name = "B", count = 3 },
new combi{id = 2, desc = "d", name = "B", count = 4 },
};
// linq group by
var result = (from row in listToLinq
group new { des = row.desc, count = row.count } by new { name = row.name, id = row.id } into obj
select new A { name = obj.Key.name, id = obj.Key.id, descriptions = (from r in obj select new B() { des = r.des, count = r.count }).ToList() }).ToList();
// validation of the results
Assert.AreEqual(2, result.Count);
Assert.AreEqual(2, result[0].descriptions.Count);
Assert.AreEqual(2, result[0].descriptions.Count);
Assert.AreEqual(2, result[1].descriptions.Count);
Assert.AreEqual(2, result[1].descriptions.Count);
}
public class A
{
public int id;
public string name;
public List<B> descriptions;
}
public class B
{
public int count;
public string des;
}
public class combi
{
public int id;
public string name;
public int count;
public string desc;
}
如果对象很小(如示例所示),这很好。 但是,我将为具有更多属性的对象实现此功能。 如何有效地编写此语句,这样我就不必在linq语句中两次写字段名称了?
我想返回语句中的对象,我想要这样的东西:
// not working wishfull thinking code
var result = (from row in listToLinq
group new { des = row.desc, count = row.count } by new { name = row.name, id = row.id } into obj
select new (A){ this = obj.key , descriptions = obj.ToList<B>()}).ToList();
背景 :我正在写一个Web api,它在单个数据库调用中检索具有嵌套对象的对象,以提高数据库性能。 从本质上讲,这是一个带有联接的大查询,它检索我需要整理为对象的大量数据。
可能很重要 :ID是唯一的。
编辑:根据到目前为止的答案,我已经为我做了一种解决方案,但是仍然有点丑陋,我希望它看起来更好。
{
// start part
return (from row in reader.AsEnumerable()
group row by row.id into grouping
select CreateA(grouping)).ToList();
}
private static A CreateA(IGrouping<object, listToLinq> grouping)
{
A retVal = StaticCreateAFunction(grouping.First());
retVal.descriptions = grouping.Select(item => StaticCreateBFunction(item)).ToList();
return ret;
}
我希望StaticCreateAFunction对于它所做的事情足够明显。 在这种情况下,我只需要写出每个属性一次,这正是我真正想要的。 但我希望有一种更聪明或更随意的方式来编写此代码。
var result = (from row in listToLinq
group new B { des = row.desc, count = row.count } by new A { name = row.name, id = row.id } into obj
select new A { name = obj.Key.name, id = obj.Key.id, descriptions = obj.ToList() }).ToList();
您可以向A
和B
类中的每个类添加一个构造函数,该构造函数接收一个combi
,然后仅从其中获取所需的内容。 例如,对于a
:
public class A
{
public A(combi c)
{
id = c.id;
name = c.name;
}
}
public class B
{
public B(combi c)
{
count = c.count;
des = c.desc;
}
}
然后,您的查询如下所示:
var result = (from row in listToLinq
group row by new { row.id, row.name } into grouping
select new A(grouping.First())
{
descriptions = grouping.Select(item => new B(item)).ToList()
}).ToList();
如果你不喜欢grouping.First()
然后你可以重写Equals
和GetHashCode
,然后在group by
通过新做的a
与相关领域(这将是那些在Equals
),然后添加一个copy constructor
从a
从combi
分离A
/ B
类的另一种方法是将转换逻辑提取到静态方法的集合中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.