C# 将来自不同来源的两个LINQ查询合并到单个对象中
我从两个不同的来源收集数据,目的是填充单个对象。我的班级是C# 将来自不同来源的两个LINQ查询合并到单个对象中,c#,linq,C#,Linq,我从两个不同的来源收集数据,目的是填充单个对象。我的班级是 public class SampleClient { public string ClientId { get; set; } public string JobName { get; set; } public string JobUrl { get; set; } public string Version { get; set; } } 第一个LINQ查询填充SampleClient对象的集合,
public class SampleClient
{
public string ClientId { get; set; }
public string JobName { get; set; }
public string JobUrl { get; set; }
public string Version { get; set; }
}
第一个LINQ查询填充SampleClient
对象的集合,获取除版本之外的所有对象的值。然后我需要遍历SampleClient
的集合,并在第二个查询中使用ClientId
值。第二个查询的结果是版本值。这是我的第一个LINQ查询:
private void btnProjects_Click(object sender, EventArgs e)
{
string[] stringArray = { "demo", "sample", "test", "training" };
List<SampleClient> jobList =
(
from x in XDocument.Load(XML URL VALUE HERE).Root.Elements("job")
where x.Element("name").Value.Contains("-config") && x.Element("name").Value.StartsWith("oba-")
&& (!stringArray.Any(s => x.Element("name").Value.Contains(s)))
select new SampleClient
{
ClientId = getClientId((string)x.Element("name")),
JobName = (string)x.Element("name"),
JobUrl = (string)x.Element("url"),
}).ToList();
foreach (SampleClient job in jobList)
{
//Display the results in a textbox
txtResults.Text += "Job Name = " + job.JobName + " | Job URL = " + job.JobUrl + " | ";
}
}
需要注意的是,第二个查询中使用的URL源是使用从第一个查询中获得的ClientId
创建的。我可以有一个例行的循环和清理/合并对象,但这感觉像一个黑客。有没有更干净的处理方法
这是第一个查询中的XML示例:
<?xml version="1.0"?>
<allView>
<description>PROD</description>
<job>
<name>abc</name>
<url>http://ci-client.company.net/job/abc/</url>
<color>blue</color>
</job>
<job>
<name>acme</name>
<url>http://ci-client.company.net/job/acme/</url>
<color>blue</color>
</job>
</allView>
戳
abc
http://ci-client.company.net/job/abc/
蓝色
顶点
http://ci-client.company.net/job/acme/
蓝色
第二个查询URL是通过使用来自第一个查询结果的clientID动态创建的。我用它来加载Maven POM文件并获取版本信息。下面是POM文件中的XML片段
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company.xyz</groupId>
<artifactId>io</artifactId>
<version>6.11.7-ACME-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<product.version>6.11.7</product.version>
<db.version>1.4</db.version>
</properties>
<modules>
<module>policies</module>
<module>templates</module>
<module>assemble</module>
</modules>
</project>
4.0.0
com.company.xyz
木卫一
6.11.7-ACME-SNAPSHOT
聚甲醛
6.11.7
1.4
政策
模板
集合
我希望我能理解你的问题
这将把它们合并在一起(尽管,我的测试数据只有ClientId、JobName和Version…)。查询1包含ClientId和JobName,查询2包含ClientId和版本
IList<SampleClient> mergedList = firstQuery.Concat(secondQuery)
.ToLookup(x => x.ClientId)
.Select(x => x.Aggregate((query1, query2) =>
new SampleClient() {
ClientId = query1.ClientId,
JobName = query1.JobName,
Version = query2.Version
}
)
).ToList();
IList mergedList=firstQuery.Concat(secondQuery)
.ToLookup(x=>x.ClientId)
.选择(x=>x.聚合((查询1,查询2)=>
新建SampleClient(){
ClientId=query1.ClientId,
JobName=query1.JobName,
Version=query2.Version
}
)
).ToList();
..可能没有手动方法那么有效。。但是,我没有任何可以作为基准的东西。请尝试以下方法:
var jobList = from x in XDocument.Load(...
where ...
let clientId = getClientId((string)x.Element("name"))
select new SampleClient
{
ClientId = clientId,
JobName = (string)x.Element("name"),
JobUrl = (string)x.Element("url"),
Version = (string)XDocument
.Load(GetSecondQueryUrl(clientId))
.Root
.Element(pom4 + "properties")
.Element(pom4 + "product.version")
};
strClientId在第二个查询中来自何处?其目的(尽管尚未完全实现)是通过循环第一个查询的结果来实现。换言之,它是来自第一个查询创建的SampleClient集合的ClientId。我希望这是有意义的。展示一个XML源的示例。如果您从已经创建的sampleClient传递strClientId,那么只需传递对象并将版本直接放在对象上。虽然我不理解第二个查询,但从您所说的,您暗示您有一个strClientId,这个查询包含许多版本……感谢您的快速反馈。我想你理解我的问题,我明天早上会试试这个。因为我是LINQ的新手,我不得不问一个可能很愚蠢的问题。您可以引用firstQuery、secondQuery以及query1和query2。你能帮我把它们的定义拼凑起来吗?再次感谢。
firstQuery
和secondQuery
只是我对您在问题中提到的两个查询的占位符。我用虚拟数据预先填充了占位符query1
和query2
是聚合用于构建返回列表的单个项。谢谢dtb。我明天早上去试试。假设这是可行的,它肯定比我想象的更干净。我真的需要学习这个LINQ的东西!
var jobList = from x in XDocument.Load(...
where ...
let clientId = getClientId((string)x.Element("name"))
select new SampleClient
{
ClientId = clientId,
JobName = (string)x.Element("name"),
JobUrl = (string)x.Element("url"),
Version = (string)XDocument
.Load(GetSecondQueryUrl(clientId))
.Root
.Element(pom4 + "properties")
.Element(pom4 + "product.version")
};