如果有以下代码,通过SQL查询从表单中检索数据:
Id subschemaName locusName
MLST MLST LMO0558
MLST MLST LMO0563
MLVST MLVST LMO1305
MLVST MLVST LMO1089
我希望将其转换为XML:
<ResponseSubschemas>
<organism>LMO</organism>
<Subschemas>
<Subschema>
<id>MLST</id>
<name>MLST</name>
<loci>
<locus>LMO0558</locus>
<locus>LMO0563</locus>
</loci>
</Subschema>
<Subschema>
<id>MLVST</id>
<name>MLVST</name>
<loci>
<locus>LMO1305</locus>
<locus>LMO1089</locus>
</loci>
</Subschema>
</Subschemas>
</ResponseSubschemas>
我是通过使用字典来实现的,但这是我第一次使用C#而且我确信必须有更高效的方法一次性完成这项工作?
string subschemaSQL = "SELECT subschema.Id, subschema.name as subschemaName, locus.Name as locusName " +
"FROM subschema " +
"LEFT JOIN subschemamembers ON subschemamembers.SubSchemaID = subschema.PrimKey " +
"LEFT JOIN locus ON subschemamembers.LocusID = locus.ID " +
"WHERE subschema.OrganismID = ? " +
"ORDER BY subschema.Id, locusName";
XElement rootNode = new XElement("ResponseSubschemas",
new XElement("organism", organismID),
new XElement("Subschemas"));
XElement subschemasNode = rootNode.Element("Subschemas");
DbDataReader subschemaReader = conn.Query(subschemaSQL, organismID);
Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
while (subschemaReader.Read())
{
string subschemaDbID = (string)subschemaReader["Id"];
XElement subschemaNode = new XElement("Subschema",
new XElement("id", subschemaDbID),
new XElement("name", subschemaReader["subschemaName"])
);
subschemasNode.Add(subschemaNode);
string locusName = (string)subschemaReader["locusName"];
if (dictionary.ContainsKey(subschemaDbID))
{
dictionary[subschemaDbID].Add(locusName);
}
else
{
dictionary.Add(subschemaDbID, new List<string> { locusName });
}
}
IEnumerable<XElement> subschemaNodes = from element in
subschemasNode.Elements("Subschema")
select element;
foreach (XElement subschemaNode in subschemaNodes)
{
string subschemaID = subschemaNode.Element("id").Value;
XElement lociNode = new XElement("loci");
foreach (string locusName in dictionary[subschemaID])
{
XElement locusNode = new XElement("locus", locusName);
lociNode.Add(locusNode);
}
subschemaNode.Add(lociNode);
}
responseXml = rootNode.ToString();
答案 0 :(得分:1)
这可能会稍微紧凑一些(尽管高层视角的内部执行与你所写的非常相似):
string subschemaSQL = "SELECT subschema.Id, subschema.name as subschemaName, locus.Name as locusName " +
"FROM subschema " +
"LEFT JOIN subschemamembers ON subschemamembers.SubSchemaID = subschema.PrimKey " +
"LEFT JOIN locus ON subschemamembers.LocusID = locus.ID " +
"WHERE subschema.OrganismID = ? " +
"ORDER BY subschema.Id, locusName";
XElement rootNode = new XElement("ResponseSubschemas",
new XElement("organism", organismID),
new XElement("Subschemas"));
XElement subschemasNode = rootNode.Element("Subschemas");
//this should probably be used in a 'using' block,
//leaving your code intact for readability:
DbDataReader subschemaReader = conn.Query(subschemaSQL, organismID);
DataTable table = new DataTable();
table.Load(subschemaReader);
subSchemasNode.Add(
table.Rows
.Select(row => new {
Id = row["id"].ToString(),
SubschemaName = row["subschemaName"].ToString(),
LocusName = row["locusName"].ToString()
})
.GroupBy(item => new { Id = item.Id, SubschemaName = item.SubschemaName)
.Select(@group =>
new XElement("Subschema",
new XElement("id", @group.Key.Id),
new XElement("name", @group.Key.SubschemaName),
new XElement("loci", @group.Select(item => new XElement("locus", item.LocusName)).ToArray())))
.ToArray());
基本上,您将所有数据加载到内存中DataTable
,然后应用处理数据集的LINQ操作,避免显式创建字典。