I am gathering data from two different sources with the intention of populating a single object. My class is
public class SampleClient
{
public string ClientId { get; set; }
public string JobName { get; set; }
public string JobUrl { get; set; }
public string Version { get; set; }
}
The first LINQ query populates a collection of SampleClient
objects obtaining values for all except Version. I then need to loop through the collection of SampleClient
and utilize ClientId
value in the second query. The result of the second query is the Version value. Here is my first LINQ query:
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 + " | ";
}
}
In the query that obtains the version, I currently have:
var version = from item in doc.Descendants(ns + "properties")
select new SampleClient
{
ClientId = strClientId,
Version = (string)item.Element(ns + "product.version").Value
};
It is important to note that the URL source used in the second query is created using the ClientId
that was obtained from the first. I could have a routine loop through and cleanup / merge objects, but this feels like a hack. Is there a cleaner way of handling this?
This is a sample of the XML from the first query:
<?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>
The second query URL is dynamically created by using the clientID from the results of the first. I am using this to load in a Maven POM file and grab version information. Here is a snippet of the XML from the POM file.
<?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>
I hope I understand your question..
This will merge them together (although, my test data only had ClientId, JobName and Version..). Query 1 contains ClientId and JobName, Query2 contains ClientId and Version.
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();
..possibly not as efficient as your manual method.. however I have nothing to benchmark against..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With