LINQ Expressions: LINQuistics of C#

Coding in C# has continuously proven to be a rewarding experience. I’m constantly learning something new in the language, and some neat little tricks to perform actions. My initial experience with C# started in game development in college; Having moved to a professional environment, however, my approach to coding in C# has changed. Lately, I’ve been doing a lot of backend development, and C# is our chosen language. I have found time and time again that LINQ expressions in C# have been the key to many major actions I needed to perform.

What is a LINQ expression?

Imagine needing to access large amounts of data from a server. You don’t need everything that’ll come back – maybe a row or a few. You would need to write several lines in SQL, stating what table to access, what other tables to combine, etc. This is not very efficient and can be time-consuming – not to mention beginning from square one if the query fails. LINQ expressions in C# effectively condense most of these statements into a single command. You can then use a dot operator to build on those commands and create more complex expressions. With how powerful they can be, you could virtually write tens of SQL statements in 5-7 lines. This increases readability as well as how concise your code is.

Also, LINQ expressions are not just used in the context of SQL statements. You can use LINQ expressions on a collection of virtually any kind in C#. In this context, LINQ expressions act more as a very powerful sort/filter tool than a data gatherer. They are, nonetheless very useful, as they enable you to quickly choose a set of data for immediate use.

How do I use a LINQ expression?

Suppose for a moment that you want to access a message in your database. You already have your SQL hierarchy set up, and a repository to access. You may use something similar to the following SQL query to get the message you’re looking for:

SELECT *
IN Messages
JOIN TABLE MessageTemplate
JOIN TABLE PlanningData
JOIN TABLE Contacts
INCLUDE ONLY COLUMN UseCases
FROM TABLE PlanningData
INCLUDE ONLY COLUMN PlanningDetails
FROM TABLE PlanningData
INCLUDE ONLY COLUMN AssemblyLineData
FROM TABLE PlanningData
INCLUDE ONLY COLUMN Contacts
FROM TABLE PlanningData
WHERE Id ON TABLE MessageTemplate = “valid-id-string”
ORDERBY COLUMN CreatedOn

This is a large query processing a large amount of data all at once. Depending on the use case of each bit of data, and how many rows exist in each table, this query could take some time to process. Using C# LINQ expressions, however, you can condense the size of this expression as well as increase its performance:

GetMessage()
.Where(x => x.id == “valid-id-string”)
.OrderBy(x => x.CreatedOn)
.Include(x => x.MessageTemplate)
.Include(x => x.Contacts)
.Include(x => x.PlanningData)
.ThenInclude(x => x.UseCases)
.ThenInclude(x => x.PlanningDetails)
.ThenInclude(x => x.AssemblyLineData)
.ThenInclude(x => x.Contacts)
.AsSplitQuery()
.FirstOrDefaultAsync();

This effectively performs the same action as the previous SQL query, except the query takes up less space. Each “.Include(…)” tells C# to join a specified table, while the “.ThenInclude()” statements ask for one specific column from said table. Moreover, the “.AsSplitQuery()” command tells C# to break up the command into chunks, which will greatly reduce the amount of time it takes to process the request. Also, the “.FirstOrDefaultAsync()” will help ensure graceful error handling if the query returns nothing. Overall, it’s quite a powerful command.

How would I use this outside of an SQL context?

Suppose you’ve retrieved a list of message templates that you want to sort through, and only retrieve their unique IDs in the database for whatever reason. You can perform this sort using the following LINQ expression:

var MessageTemplateIds = templates
.Select(x => x.Id)
.Distinct()
.ToList();

This statement will begin by grabbing a single element from each object – the ID. I find this to be particularly useful as it won’t require me to manually separate the element from the object and store it elsewhere. What would have been a multi-line command is now one single function.

Next, it iterates through every ID it has found and removes duplicates. Again — this is quite powerful, as a function like that would also take several lines to write out manually. Finally, it compiles every distinct ID it has found into an array.

Can I use LINQ expressions to create mock data?

You definitely can use LINQ expressions to create mock data. For example, suppose you wanted to create a mock Message object for a test. You could do the following, using the built-in AutoFixture feature:

public static readonly MessageObject = AutoFixture
.Build()
.With(x => x.Message, “Message”)
.With(x => x.Sender, “Sender”)
.With(x => x.Receiver, “Receiver”)
.Without(x => x.SendDate)
.Create();

What this LINQ expression will do first is create a Message Data object. Then, it will fill the message field with a specified message and assign a sender. Finally, it will specify the receiver, tell the AutoFixture not to associate a send date, and create the object. Once it’s created, you can use this object wherever you need.

LINQ expressions have many uses not just limited to these three instances. Try them out in your own C# project and make something awesome and powerful.

 
Conversation

Join the conversation

Your email address will not be published. Required fields are marked *