Combine two LINQ queries from different sources into one object

I collect data from two different sources in order to fill one object. My class

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 that receive values ​​for all but the version. Then I need to loop through SampleClient and use the ClientId value in the second request. The result of the second query is Version. 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 request that gets 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 request is created using the ClientId , which was obtained from the first. I may have a regular loop and cleanup / merge objects, but this seems like a hack. Is there a cleaner way to handle this?

This is an XML sample from the first request:

 <?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 request URL is dynamically generated using the clientID from the results of the first. I use this to download the Maven POM file and get version information. Here is the XML fragment 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> 
+4
source share
2 answers

Try the following:

 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") }; 
0
source

I hope I understand your question.

This will combine them together (although in my test data there were only 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(); 

.. maybe not as effective as your manual method. However, I have nothing to compare with.

+2
source

Source: https://habr.com/ru/post/1445422/


All Articles