我正在通过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,它在单个数据库调用中检索具有嵌套对象的对象,以实现db性能。它基本上是一个带有连接的大查询,它可以检索我需要整理到对象中的垃圾数据。
可能很重要: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足够明显。在这种情况下,我只需要写出一次属性,这就是我真正想要的。但是我希望有一种更聪明或更流行的方式来写这个。
答案 0 :(得分:1)
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();
答案 1 :(得分:1)
您可以向每个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
1}}包含相关字段(将是Equals
中的字段),然后从copy constructor
a
另一种方法是将A
/ B
类与combi
分离,将转换逻辑提取为静态方法的集合。