Microsoft Orange Badge
Microsoft Orange Badge

Reputation: 469

Where does the LINQ query syntax come from?

I'm new to C# and have just started to delve into using classes that essentially mirror a database. What I'm confused about is how I'm able to use lines like

var queryLondonCustomers = from cust in customers
                           where cust.City == "London" 
                           select cust;

in my program. From what I understand, that syntax isn't "normal" C#, so the above line wouldn't have any meaning if I hadn't included System.Linq. What is happening is we've added to the C# sharp language in the context of this file.

Maybe I'm completely wrong. Could someone clear this up for me? I come from a C++ background, so maybe I'd understand if someone could show me the C++ equivalent of this concept.

And if I'm right, why is this way of doing things preferable to having a C# class that talks to the database by using strings that are database queries, like with PHP and MySQL? I thought this MVC way of talking to the database was supposed to provide an abstraction for me to use a C# class for database operations, but really this is just taking database language and adding it to the C# language in the context of a particular C# file. I can't see any point of that. I'm not trolling, just trying to understand the spirit of this whole ASP.NET MVC thing that is the most confusing thing I've learned so far.

Upvotes: 0

Views: 263

Answers (4)

xanatos
xanatos

Reputation: 111940

in my program. From what I understand, that syntax isn't "normal" C#, so the above line wouldn't have any meaning if I hadn't included System.Linq

Yes and no at the same time :-)

The LINQ syntax is standard C# syntax (from C# 3), but it is resolved at compile time as a semi-textual substitution...

Your code is changed to:

var queryLondonCustomers = customers.Where(cust => cust.City == "London");

and then the various .Where and .Select methods are resolved (it is called Duck Typing... see for example Does LINQ "Query Syntax" Support Duck Typing?)

So at this point you need the using System.Linq that gives you access to the System.Linq.Enumerable and System.Linq.Queryable that are the two classes that implement all the various .Where and .Select methods as extension methods.

Note that you could create and implement a static class of yours, public static class MyLinqMethods, and by creating methods with the "right" signature in that class, you could use the LINQ syntax against your MyLinqMethods class.

And if I'm right, why is this way of doing things preferable to having a C# class that talks to the database by using strings that are database queries

There is some safety in using LINQ... If you created somewhere some classes that mapped the database tables, then the C# compiler could check against these classes that you are using the right names for the fields. If you wrote

var queryLondonCustomers = from cust in customers
                           where cust.CityERROR == "London" 
                           select cust;

the compiler would give you an error, because CityERROR isn't a field/property of Customer. Clearly you could have an error in the "mapping" files, but at least you have a single place that can have these errors.

Upvotes: 3

Jon Hanna
Jon Hanna

Reputation: 113372

From what I understand, that syntax isn't "normal" C#,

Yes it is.

so the above line wouldn't have any meaning if I hadn't included System.Linq

It would. It would always mean the same thing as:

var queryLondonCustomers = customers.Where(cust.City == "London");

C# doesn't care how customers.Where(Func<Customer, bool>) is defined, just as long as it is. System.Linq has extension methods that define Where for IEnumerable and IQueryable which covers 99.9% of the time that you want this, but it doesn't have to come from there.

In particular if customers was an instance of a class that had its own Where(Func<Customer, bool>) method then it would be the overload used (instance methods always beat extension methods in overload resolution). Likewise if another static class defined an extension method for ... Where(this CustomerCollection, Func<Customer, bool>) or similar it would be called.

And if I'm right, why is this way of doing things preferable to having a C# class that talks to the database by using strings that are database queries

Querying collection-like objects is a very common use case, of which database access is only one. Providing a common interface to a common use case is a classic reason for any interface-based programming.

Upvotes: 1

hbulens
hbulens

Reputation: 1969

ASP.NET MVC is just a way of creating web applications, like you would create windows forms or WPF projects to create desktop applications. They don't have any special capabilities regarding database interaction .

LINQ on the other hand is something that is quite unique. It provides a convenient way of working with collections. The data in these collections can come from databases but it doesn't have to. How you write your queries depend on your preference. I like the lambda syntax, it is short and easy to read.

The advantage of LINQ is that you CAN use its syntax to interact with the database, but therefore you'll need to use APIs that are designed to do this, such as entity framework. This way, you can tell entity framework to do certain stuff with your LINQ commands, such as retrieving records with a certain where clause.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1503280

From what I understand, that syntax isn't "normal" C#

Yes it is, as of C# 3.

so the above line wouldn't have any meaning if I hadn't included System.Linq

Yes it would. It would still have effectively been transformed by the compiler into:

var queryLondonCustomers = customers.Where(cust => cust.City == "London");

(The lack of a Select call is because you're selecting the range variable directly, rather than some projection of it.)

If that code would have compiled (e.g. because of a Where member in customers, or due to another extension method on its type) then so would the query expression.

Query expressions are specified in section 7.16 of the C# language specification.

As for the question of why you'd want to do this, well:

  • Using an ORM instead of just manual SQL is hardly new - but LINQ integrates it into the language, with a somewhat leaky abstraction
  • LINQ doesn't just work for databases; I primarily use it in "regular" collections such as lists etc.

Upvotes: 4

Related Questions