我列出了XML的加载。
XML看起来像这样:
<TablesToSynchronize>
<Table name="dbo.Table1" />
<Table name="dbo.Table2" />
<Table name="dbo.Table3" />
<Table name="dbo.Table4" />
</TablesToSynchronize>
我想将XElement
的列表与string
列表进行比较,但我无法将其整合在一起。
private static readonly XDocument TableSettings = XDocument.Load(GetAssemblyDirectory() + @"\Tables.xml");
private static List<XElement> TablesToSync = new List<XElement>();
static void Main(string[] args)
{
{
var test = TableSettings.Descendants("Table").Select(x => x.Attribute("name").Value.ToString());
test = test.Where(args.ToList().Contains).ToList();
var test2 = (from x in TableSettings.Descendants("Table")
where x.Attribute("name").Value == "dbo.Table1"
select x).ToList();
//TablesToSync = ??
}
}
var test2
工作正常,但只返回带有“Table1”的XElement
。我想循环args并检查是否有任何项目匹配XElement
属性("name").Value
。
我在这里缺少什么?
args包含dbo.Table1,dbo.Table2,dbo.Table3
更新:test2给我一个包含dbo.Table1的XElement
列表。 test给了我一个string
的空列表。
输出应为List<XElement>
答案 0 :(得分:1)
有两种方法可以使用Where
来实现您想要的效果,使用JOIN
您可以应用联接以获得结果
var mytest = TableSettings.Descendants("Table").Join(arggs, x => x.Attribute("name").Value, y => y, (x, y) => new { Element = x });
您可以将Where
应用为
TablesToSync = TableSettings.Descendants("Table").Where(x => arggs.Contains(x.Attribute("name").Value)).ToList();
如果您的数据很小,那么它不应该为您决定使用哪一项提供很多性能改进。但是如果你有大量的数据阅读评论和更多的东西,你应该自己决定你想要遵循哪种方法。
答案 1 :(得分:1)
以下内容将返回两个元素:
args = new[] { "dbo.Table1", "dbo.Table3" };
var test = (from elt in TableSettings.Descendants("Table")
where args.Contains(elt.Attribute("name").Value)
select elt).ToList();
Debug.Assert(test.Count==2);
或
args = new[] { "dbo.Table1", "dbo.Table3" };
var test = (from elt in TableSettings.Descendants("Table")
where args.Contains((string)elt.Attribute("name"))
select elt).ToList();
或作为方法链的等价物:
var test = TableSettings.Descendants("Table")
.Where(elt => args.Contains(elt.Attribute("name").Value))
.ToList();
XAttribute可显式转换为基本.NET类型之一,因此您必须使用(string)
强制转换。否则,.NET会将XAttribute实例与字符串值进行比较。
如果您有很多参数并且担心Contains
很慢,您可以将字符串数组转换为字典:
var argsDict = args.ToDictionary(x => x);
var test = TableSettings.Descendants("Table").
Where(elt => argsDict.ContainsKey(elt.Attribute("name").Value))
.ToList();
对10000000次迭代的快速测试会返回这些非常有意义的结果:
Where
和Join
之间的差异可以忽略不计(~2%),很容易归因于噪音。字典或散列集虽然明显更快(~30%)。
事实上,等效方法之间的差异波动很大,基本上没有意义。
这并不令人惊讶,因为字典/ hashset本质上充当了SQL中的索引。事实上,当连接中的两个表中的一个表(相对)很小时,SQL Server将使用散列连接。
如果您需要从参数中访问多个键,字典可能会执行得更好,因为您可以在单个操作中查找和检索匹配值。这类似于在SQL中使用覆盖索引:
MyOtherClass v=null;
var test = from elt in TableSettings.Descendants("Table")
let value = elt.Attribute("name").Value
where argsDict.TryGetValue(value, out v)
select new {elt, v};
这在C#5中相当丑陋。这是C#6中(现已废弃的)声明表达式有帮助的地方:
var test = from elt in TableSettings.Descendants("Table")
let value = elt.Attribute("name").Value
where argsDict.TryGetValue(value, out var v)
select new {elt, v};