我有两个课程可以说
class Foo
{
List<Bar> Bars{get;set;}
}
class Bar
{
string Name{get;set;}
string Value{get;set;}
}
我有这样的查询
var resultsGroupedByState=Foos.GroupBy(x=>x.Bars.First(c=>c.Name=="state").Value);
将返回按州分组的结果,而且用户可以按字段定义组的层次结构,例如
我要做多少级别的小组,我不知道。我要在层次结构中首先定义一个groupby,然后在第一个groupby的结果的基础上进行基于第二个值的groupby,并继续。
最后我要从这些数据中生成一个xml。
<State value="anyState">
<County value="anyCounty">
<City value="anyCity">
..........
</City>
</County>
</State>
答案 0 :(得分:1)
基本上你需要生成XML。一种解决方案可以是递归执行GroupBy
并直接创建XMLDocument
。
这是一个可以做到这一点的助手类。
public class XmlGenerator
{
private XmlDocument _document;
private List<string> _fields;
private int index = 0;
public XmlGenerator(List<string> fields)
{
_fields = fields;
}
public void GenerateXML(IEnumerable<Foo> lookupData, XmlElement root, string field)
{
var fieldGrouping = lookupData.GroupBy(v => v.Bars.First(x => x.Name == field).Value);
foreach (var grouping in fieldGrouping)
{
var element = _document.CreateElement(field);
var attrib = _document.CreateAttribute("value");
attrib.InnerText = grouping.Key;
element.Attributes.Append(attrib);
root.AppendChild(element);
// If that is last field. No need to do any grouping.
if (index < _fields.Count - 1)
{
// After each nested call update the nested level.
// If GenerateXML do another that will be upon next nested level
index += 1;
GenerateXML(grouping, element, _fields[index]);
index -= 1;
// Make sure to change back nested level index otherwise that will not works if you have multiple groups.
}
}
}
public string GenerateXML(IEnumerable<Foo> lookupData)
{
_document = new XmlDocument();
var root = _document.CreateElement("Root");
_document.AppendChild(root);
index = 0;
GenerateXML(lookupData, root, _fields[index]);
return _document.OuterXml;
}
}
我在这里做的实际上是,我已经在List<string>.
内存储了所有字段列表并编写了一个按特定字段分组的辅助方法。每次传递时,我都会传递需要分组的方法数据和要分组的字段名称。
希望如此,这解决了你的问题。
答案 1 :(得分:-1)
你不需要GrroupBy。试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<Root>" +
"<State value=\"AState\">" +
"<County value=\"ACounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"<County value=\"BCounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"<County value=\"CCounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"</State>" +
"<State value=\"BState\">" +
"<County value=\"ACounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"<County value=\"BCounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"<County value=\"CCounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"</State>" +
"<State value=\"CState\">" +
"<County value=\"ACounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"<County value=\"BCounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"<County value=\"CCounty\">" +
"<City value=\"ACity\"/>" +
"<City value=\"BCity\"/>" +
"<City value=\"CCity\"/>" +
"</County>" +
"</State>" +
"</Root>";
XElement root = XElement.Parse(xml);
List<Foo> foos = Helper(root);
}
public static List<Foo> Helper(XElement element)
{
if (element.HasElements)
{
string tagName = ((XElement)element.FirstNode).Name.LocalName;
List<Foo> children = element.Elements(tagName).Select(x => new Foo()
{
Name = tagName,
Value = (string)x.Attribute("value"),
foos = Helper(x)
}).ToList();
return children;
}
else
{
return null;
}
}
}
public class Foo
{
public string Name { get; set; }
public string Value { get; set; }
public List<Foo> foos { get; set; }
}
}