关于c#:LINQ查询语法从何而来?

 2021-02-24 

Where does the LINQ query syntax come from?

我是C#的新手,刚刚开始研究使用本质上反映数据库的类。我感到困惑的是如何使用

之类的行

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

在我的程序中。据我了解,该语法不是"普通的" C#,因此如果我没有包含System.Linq,则以上行将没有任何意义。发生的事情是我们已在此文件的上下文中将其添加到C#锋利语言中。

也许我完全错了。有人可以帮我清理一下吗?我来自C语言,所以也许我会理解是否有人可以向我展示该概念的C语言。

如果我是对的,为什么这种方法比使用C#类通过使用数据库查询字符串(例如PHP和MySQL)与数据库进行对话更好呢?我以为这种与数据库的MVC对话方式应该为我提供了一种使用C#类进行数据库操作的抽象方法,但实际上这只是采用数据库语言并将其添加到特定C#文件的上下文中的C#语言中。我看不到这一点。我并不是在拖延,只是试图了解整个ASP.NET MVC的精神,这是到目前为止我学到的最令人困惑的事情。


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

是和否同时:-)

LINQ语法是标准的C#语法(来自C#3),但在编译时作为半文本替换而解析...

您的代码已更改为:

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

,然后解析各种.Where.Select方法(这被称为Duck Typing ...,例如,请参见LINQ " Query Syntax "是否支持Duck Typing?)

因此,在这一点上,您需要using System.Linq以便可以访问System.Linq.EnumerableSystem.Linq.Queryable,这是两个将所有.Where.Select方法实现为扩展方法的类。

请注意,您可以创建并实现您的静态类public static class MyLinqMethods,并通过在该类中创建带有" right "签名的方法,可以对MyLinqMethods类使用LINQ语法。铅>

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

使用LINQ有一定的安全性...如果在某个地方创建了一些映射数据库表的类,则C#编译器可以针对这些类检查您是否使用了正确的字段名称。如果您写了

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

编译器会给您一个错误,因为CityERROR不是Customer的字段/属性。显然," mapping "文件中可能有一个错误,但是至少您只有一个地方可以出现这些错误。


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

是的,从C#3开始。

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

是的。编译器仍然可以有效地将其转换为:

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

(缺少Select调用是因为您正在直接选择范围变量,而不是它的某些投影。)

如果该代码已经编译过(例如由于customers中的Where成员或由于其类型上的其他扩展方法),则查询表达式也将进行编译。

查询表达式在C#语言规范的7.16节中指定。

关于您为什么要这样做的问题,很好:

  • 使用ORM代替仅使用手动SQL并不是什么新鲜事物-但是LINQ将其集成到语言中,带有某种程度的泄漏抽象
  • LINQ不仅适用于数据库。我主要在"常规"集合(例如列表等)中使用它。


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

会的。它总是与以下内容相同:

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

C#并不关心customers.Where(Func<Customer, bool>)的定义方式,只要定义就可以。 System.Linq具有可为IEnumerableIQueryable定义Where的扩展方法,该方法可以覆盖99.9%的时间,但不必从那里来。

尤其是如果customers是具有自己的Where(Func<Customer, bool>)方法的类的实例,则将使用重载(实例方法在重载解析中始终胜过扩展方法)。同样,如果另一个静态类为... Where(this CustomerCollection, Func<Customer, bool>)或类似方法定义了扩展方法,则将其称为

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

查询类似集合的对象是一种非常常见的用例,其中只有数据库访问权限。为通用用例提供通用接口是任何基于接口的编程的经典原因。


ASP.NET MVC只是创建Web应用程序的一种方式,就像您创建Windows窗体或WPF项目创建桌面应用程序一样。他们没有关于数据库交互的任何特殊功能。

另一方面,LINQ是非常独特的。它提供了使用集合的便捷方法。这些集合中的数据可以来自数据库,但不是必须的。您如何编写查询取决于您的喜好。我喜欢lambda语法,它简短易读。

LINQ的优点是您可以使用其语法与数据库进行交互,但是因此您将需要使用为此目的而设计的API,例如实体框架。这样,您可以告诉实体框架使用LINQ命令执行某些操作,例如使用某个where子句检索记录。