我试图理解如何将LINQ-to-XML和LINQ-to-SQL查询结合起来,并执行连接。
具体来说,我有一个包含城市,县和州信息的SQL表,我可以用LINQ to SQL查询它,但在同一个查询中,我想加入具有相同状态的SQL行和/或县,并生成XML作为输出的一部分。
这是我的表格的大概:
╔═════╦══════════════╦════════════════╦═══════╗
║ IDX ║ CITY ║ COUNTY ║ STATE ║
╠═════╬══════════════╬════════════════╬═══════╣
║ 1 ║ YAKUTAT ║ ALEUTIANS EAST ║ AK ║
║ 2 ║ city-1 ║ ALEUTIANS EAST ║ AK ║
║ 3 ║ city-2 ║ ALEUTIANS EAST ║ AK ║
║ 4 ║ city-3 ║ ALEUTIANS WEST ║ AK ║
║ 5 ║ city-4 ║ ALEUTIANS WEST ║ AK ║
║ 6 ║ city-5 ║ ALEUTIANS WEST ║ AK ║
║ 7 ║ xyz ║ ANCHORAGE ║ AK ║
║ 8 ║ abc ║ BETHEL ║ AK ║
║ 9 ║ lmnop ║ WYOMING ║ NY ║
║ 10 ║ pqrst ║ WARSAW ║ NY ║
║ 11 ║ defg ║ WARSAW ║ NY ║
╚═════╩══════════════╩════════════════╩═══════╝
这就是我希望我的XML输出看起来像。我希望联接将所有同一县的城市分组为同一县节点下的节点,然后将状态中的所有县分组为状态节点的子节点。
<State>AK</State>
<County>ALEUTIANS EAST</County>
<City>YAKUTAT</City>
<City>city-1</City>
<City>city-2</City>
<County>ALEUTIANS WEST</County>
<City>city-3</City>
<City>city-4</City>
<City>city-5</City>
<County>ANCHORAGE</County>
<City>xyz</City>
<County>BETHEL</County>
<City>abc</City>
<State>NY</State>
<County>WYOMING</County>
<City>lmnop</City>
<County>WARSAW</County>
<City>pqrst</City>
<City>defg</City>
我确实有部分工作,我能够成功地从我的数据库中选择行,并且我能够将输出写为XML,但我无法将城市和县数据嵌套为状态的子节点,并且我错过了加入部分,目前尚不清楚如何做到这一点。
XDocument xDoc = new XDocument(new XElement("States",
(from states in state.Database
select new XElement(new XElement("State",states.State),
new XElelment("County",states.County),
new XElelment("City",state.City))));
xDoc.Save("C:\\states.xml")
这是我得到的输出。正如您所看到的,我在没有层次结构的情况下获得了数据库中所有城市,州和县的完整列表。
<State>AK</State>
<County>ALEUTIANS EAST</County>
<City>YAKUTAT</City>
<State>AK</State>
<County>ALEUTIANS EAST</County>
<City>city-1</City>
<State>AK</State>
<County>ALEUTIANS EAST</County>
<City>city-2</City>
<State>AK</State>
<County>ALEUTIANS WEST</County>
<City>city-3</City>
<State>AK</State>
<County>ALEUTIANS WEST</County>
<City>city-4</City>
....and so on..
答案 0 :(得分:0)
你真的有几个不同的问题,首先是你无法生成一个分层的XML文件(假设我在编辑你的问题之前理解你的原始意图)。实际上,您的示例XML甚至不是分层的,因为您在嵌套其下方的预期子标记之前关闭标记。像你正在做的缩进不是创建任何类型的子节点,只是让它看起来像。
我认为您希望XML看起来像这样:
<State>AK
<County>ALEUTIANS EAST
<City>YAKUTAT</city>
<City>city-1</city>
</County>
</State>
但是混合简单类型(如字符串与复杂类型,如同一节点中的其他节点)可能会非常混乱。我可以建议修改结构以使用属性,从而消除一些令人困惑的层次结构。像这样的结构更常被接受:
<State name = "AK">
<County name = "ALEUTIANS EAST">
<City>YAKUTAT</city>
<City>city-1</city>
</County>
</State>
生成嵌套XML只是将XElement
对象排列在彼此内部的问题
XElement stateElement = new XElement("State", new XAttribute("name", "AK"),
new XElement("County", new XAttribute("name", "ALEUTIANS EAST"),
new XElement("City", "YAKUTAT"),
new XElement("City", "city-1")));
将生成一个具有上面建议结构的XML。
您缺少的第二部分是加入。由于所有内容都在同一个表中,因此您实际上在寻找一个组查询,因为您希望将子元素组合在一个共同的父项下。
我不期望LINQ-to-SQL,以及不同口味之间可能存在字幕差异的事实,我不是100%肯定语法是完全正确的,但希望如果它关闭,它仍然会让你指向正确的方向。
请注意,仅仅因为您正在创建XML文件,这不是LINQ-to-XML,LINQ是关于查询源而不是输出,因为您正在查询数据库,这是LINQ-to -SQL
var query = from states in state.Database
group states by new { states.State, states.County } into countyGroup
group countyGroup by countyGroup.Key.State into stateGroup
select new XElement("State", new XAttribute("name", stateGroup.Key),
stateGroup.Select(st => new XElement("County", new XAttribute("name", st.Key.County),
st.Select(city => new XElement("City", city.City)))));
var xdoc = new XDocument(new XDeclaration("1.0", "UTF-8", null),
new XElement("States", query.ToArray()));
第一个组语句将根据公共县和州将所有数据库行分组(有必要包括状态,就好像您将其排除在Orange,FL和Orange中的城市一样,CA将被组合在一起。然后,第二个组语句将您的数据库行进一步分组为常见状态。最终得到一个分组(称为stateGroup
,它由同一个县的一组城市组成,并且在同一个城市中分组的县
将分组分成适当的XML节点的select语句变得非常混乱,但是它有效地写出每个分组以便到达我认为你想去的地方。
(当你在问题中创建XDocument
时,你也错过了XML声明,所以我在这里添加了。)