Ankur Ankur - 3 years ago 171
C# Question

Select from List of detaisl using linq

Hi below is my format in which my object data is stored. I am new to linq.

Server1, Database, MySQL, 5.5
Server2, Database, MySQL, 5.1
Server3, OS, Ubuntu, 10.04
Server1, OS, Ubuntu, 10.04
Server2, OS, Ubuntu, 12.04
Server3, Language, Python, 2.6.3


Below is my class structure.

public class dettails
{
public string server { get; set; }
public string details1 { get; set; }
public string details2 { get; set; }
public string version { get; set; }

public dettails(string Server, string Details1, string Details2, string Version)
{
server = Server;
details1 = Details1;
details2 = Details2;
version = Version;
}
}


Below is code that haas added data in my List of object.

List<dettails> objEmps = new List<dettails>();
while ((line = sr.ReadLine()) != null)
{
objEmps.Add(new dettails(fields[0].ToString().Trim(), fields[1].ToString().Trim(), fields[2].ToString().Trim(), fields[3].ToString().Trim()));
}


I want an output using linq like below.

A list of software package names for which an out-of-date version (i.e. a version which is not the latest version) is installed on at least 2 different servers.

Thus, in this case, the output of your program should be:

Ubuntu
Because Ubuntu 10.04 is an out-of-date version (the latest version is 12.04), and it is installed on two servers (Server 3, and Server 1).

How can i achieve it using linq. Please advice

Answer Source

Here is some LINQ to find that Ubuntu is out of date. If you need the full explanation as you write in the question to be output, that will be a lot more work.

var detailList = new List<dettails>()
{
    new dettails("Server1", "Database", "MySQL", "5.5"),
    new dettails("Server2", "Database", "MySQL", "5.1"),
    new dettails("Server3", "OS", "Ubuntu", "10.04"),
    new dettails("Server1", "OS", "Ubuntu", "10.04"),
    new dettails("Server2", "OS", "Ubuntu", "12.04"),
    new dettails("Server3", "Language", "Python", "2.6.3")
};

// 2. group details into software
var softwareGrouping = detailList.GroupBy(d => new {d.details1, d.details2});

// find software matching criteria
var obsoleteSoftware = softwareGrouping.Where(sg => sg
    // first split into versions
    .GroupBy(z => z.version)
    // sort version groups by the version number (oversimplified method)
    .OrderByDescending(z => z.Key)
    // ignore latest version
    .Skip(1)
    // get versions where installation count is greater than 1
    .Where(ss => ss.Count() > 1)
    // return if there are any old versions found
    .Any()
);

// 3. now create a result object for each found version
var results = obsoleteSoftware.Select(y => y.Key);

/* A more condensed version
var results = detailList.GroupBy(x => new {x.details1, x.details2})
    .Where(y => y.GroupBy(z => z.version).OrderByDescending(z => z.Key).Skip(1).Where(ss => ss.Count() > 1).Any())
  .Select(y => y.Key);
*/

foreach(var res in results)
{
    Console.WriteLine("{0}, {1}", res.details1, res.details2);
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download