LINQ TRINKETS

LINQ EXAMPLES. LINQ is probably one of the main reasons why I’ve stuck with C#. It’s such a powerful in memory data manipulation namespace in dotNet and the main reason why you can abbreviate tens of lines of code into one.

I’ve accumulated a few queries which I use regularly which I hope you may find useful and which I know I’ll be referring to again.

The examples below are based on the following class Model

Linq-1.PNG

and the following xml

Linq-2.PNG

Importing XML into a List of T

This code takes the above xml file and converts it into a List

Linq-3.PNG

XDocument xDoc = XDocument.Load(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "AdvancedSearchesCsvs.xml"));

var Csvs = xDoc

.Descendants("Csv")

.Select(r => new ModelCsv

{

Csv = r.Element("CsvName").Value,

RCode = r.Attribute("ReadCode").Value

}).ToList();

Parsing a DataSet into a List of T

Lets say you have created a dataset from a SQL Query and want to parse it into a List

In this case the Dataset has a column called “CsvName” and a column called “ReadCode”.

Linq-4.PNG

var Csvs = ds.Tables[0].AsEnumerable().Select(r => new ModelCsv

{

Csv = r.Field("CsvName"),

RCode = r.Field("ReadCode")

}).ToList();

Changing the value of a property in a List of T

There are times when you want to just change the value of one of the properties in a List of Objects without having to unwravel it, change the property then bundle it up again

Csvs is your List and you would like to change the value of RCode to another value (which you could have in a foreach). In this example

Linq-5.PNG

Csvs.Where(s => s.RCode == "READCODE TO CHANGE").Select(r =>

{

r.RCode = "CHANGED READCODE VALUE";

return r;

}).ToList();

Convert a List of T into a Dictionary

This stumped me for a little while but got it in the end. The key is to create a anonymous object then assign the properties of this object to the Key and Value of the Dictionary.

In this example the List is a List

Linq-6.PNG

var csvDictionary = new Dictionary<string, string>(Csvs.Select(l => new

{

CsvName = l.Csv,

ReadCode = l.RCode

}).ToDictionary(k => k.CsvName, k => k.ReadCode));

Reorder an List of T removing duplicates of one property

Useful if you want to reorganise your List of T to only have a unique value in one property which is different to .Distinct() which will only create unique entries of the objects container.

In this example you already have a List of modelCsvs

Linq-7.PNG

modelCsvs = modelCsvs.GroupBy(r => r.PatientID)

.Select(g => g.FirstOrDefault())

.OrderBy(r => r.PatientID)

.ToList();

This will take the modelCsvs and redo them removing duplicate patients.

You can also convert to a hashset and convert back

var noDupsList = new HashSet<T>(withDupes).ToList();

You can also select distinct by more than one property using DistinctBy as below but you need to have MoreLinq installed to do this.

modelCsvs.DistinctBy(m => new { m.PatientID, m.ReadCode}).ToList();

Comparing 2 lists with one shared property

Sometimes you have 2 lists and you want to select objects which property values between both.

For example lets say we have another List of Patients with ReadCodes as one of their values which we will call ExternalPatients and we want to know which of these patients are already on our original List of ModelCsvs.

This is similar to a List.Contains() Method but allows you to select a property of an object instead. List.Contains() can only be used with simple types.

Linq-8.PNG

patientsCommonOnBoth =

modelCsvs.Where(m =>

ExternalPatients.Any(e => e.ReadCode == m.ReadCode))

.ToList();

Checking to see if a value is in a property of a list of object

With this query you are able to see if a value is in a list of objects. For example you have a list of Code Objects one property of which contains a ReadCode field. This query checks to see if a queried readcode is in this list of objects

if (_readCodesForSharedDB.Any(r=>r.ReadCode == adminReadCodetoInsert.ReadCode))

Removing patients from a list which is contained within another list

This is different to Intersect (which takes the same value) and Excerpt (which like a Union minus and Intersect) and removes common items in two lists leaving the larger list but without the common items

For example lets say we have another List of External Patients which are also in ModelCsvs and we want to remove these patients from the modelCsvs to leave us with modelCsvs - External Patients. This is how we would do it

This is similar to a List.Contains() Method but allows you to select a property of an object instead. List.Contains() can only be used with simple types.

var patientsNotCommonToBothLists= modelCsvs

.Where(m => ExternalPatients.All(e => e.ReadCode!= m.ReadCode)).ToList();

Ordering via id then removing the oldest values from the date property

Frequently you have a raw list of patients with with ids and date of test done and you want to just choose the latest test result of each patient. This Query will help you achieve this.

list = list

.GroupBy(x => x.RefId)

.SelectMany(x => x.OrderByDescending(y => y.Date).Take(1))

.ToList();

Now we have a little repository of examples which you might find useful on your travels.

Photo credit: jDevaun.Photography / Foter / CC BY-ND

Previous
Previous

DECOUPLING CODE

Next
Next

FROG IN A WELL & EVENT HANDLERS