MVC北京一卡通绑定实体卡多个实体时,验证信息为什么不显示

能代替LINQ to Entities的另一种可以创建的查询方法是直接使用EF的对象服务(Ojbect Services),它在中使用的查询语言,不光是在EF中。它强大的拼写也使它更容易组织。然而,LINQ并不能在每个场景下使用。它是C#和VB的一部分,但没有成为.NET其它语言的一部分。此外,在后面你将学习到当你不需要具体对象时在DataReaders中查询流式结果。这个只有Entity SQL表达式能做到。正如你将在第5章及后面的章节中看到的,在某些场景下可以创建Entity SQL字符串更有优势。因此,尽管你使用LINQ to Entities完成大部分查询,当你遇到这些少见的案例时,你将有所准备。

实体SQL(ESQL)的确是第一个用来查询实体的语法。LINQ由VB和C#语言小组作为语言扩展开发出来,最终很明显LINQ是EF极好的附加,这也是LINQ to Entities的由来。

实体SQL起源于SQL,因为从众所周知的东西开始是有意义的。然而,因为实体不同于关系数据,实体SQL脱离了SQL为查询EDM提供了必要的功能。

EF文档有一个话题叫"实体SQL与Transact-SQL哪里不同"。它提供了一个差别列表,还有每个差异的解释说明。例如,实体SQL支持EDM中的继承和关系,而T-SQL你必须使用joins来实现关系。关系数据库甚至没有继承的概念;因此,T-SQL也不支持继承。

仔细看一下前面写到实体SQL查询字符串,你会注意到,像LINQ to Entities一样,它定义了用于查询的变量c,在LINQ中它被称为控制变量,但是在实体SQL中它只是个变量。

图3-6分析了除了WHERE子句之外的查询字符串。变量使用AS关键字定义,只在SELECT子句引用到。VALUE关键字指定你想要返回的单项的集合;在这里它是Contact实体。

如果你要选择单个类型VALUE子句是必须的,单个类型可以是实体,某个属性,基础实体集合,还有你想要返回强类型的对象。这在下面的代码片段中展示:

SELECT VALUE c FROM 框架的SQL Server提供程序提供了大约75个特殊的函数,在目标数据库是SQL Server时你可以在实体SQL查询中使用它。它们中的有些与标准函数有所重叠。提供程序此外还提供了特定提供程序原生的类型和它们的方面,还有用于映射EDM和SQL Server的内在的逻辑。其它为EDM编写的提供程序将会有他们支持的自己的附加函数和特性的列表。

注:记住使用EF查询最大的一个好处是它是不依托数据库的。因此,在实体SQL查询中使用提供程序特有的元素前你应该考虑这一点。

注:如果你熟悉T-SQL,你将非常高兴有一个标准函数是Trim(),它意味着你不用傻傻地到处使用LTRIM(RTRIM())了。

对象查询(ObjectQuery)允许你创建参数化的查询。与其它查询语言类似,你在字符中使用@占位符,然后在参数中定义它的值。

要使用参数化的查询,你可以给为对象查询增加使用ObjectContext中的CreateQuery方法创建的参数,或者添加到你显式实例化的对象。如示例3-4。当你在实例化对象查询时你也需要将ObjectContext作为参数传递。

然后你在执行前为对象查询增加参数。为了明白这是如何工作的,你可以重写之前的查询,允许动态改变查询。见示例3-4。

你可以使用这些方法语法直接编写查询,如果你更喜欢的话。很多开发人员确实更喜欢这样,尽管其它人喜欢使用查询表达式语法。MSDN文档说,"通常来说,我们推荐查询语法,因为它通常更为简单和可读;然而,方法语法和查询语法并没有本质的不同"。因此,使用哪一种只是类型和个人选择的问题。

编写基于方法的查询,你先要知道在.NET 3.5引用的特性,叫做lambdas表达式。Lambda表达式有着特殊语法的内联方法。如果你是LINQ和lambda表达的新手,从示使用过匿名委托,在看过一些示例后你会弄明白。

在这我们将看一下你在之前示例中使用过的查询,现在使用基于方法的查询编写它。在VB中,表达式以Function开始,表示你正在控制变量上执行函数;然后它呈述了条件。控制变量,这个示例中是c,又在忙碌了。

C#的使用基于方法的LINQ to Entities查询语法看起来非常不同:

注:在Where子句中,返回布尔类型的表达式称为谓语(predicate)。是查询将返回使用表达式值为True的所有contacts。

  1. 使用一个方法查询替换现有的查询。你将看到在书写lambda时智能感知非常有帮助。

  2. 按下F5运行应用程序。结果同前面一样。

你可以联合LINQ查询方法构建更实用的表达式。这被称为链接。为了试一下这个,为之前查询添加一个OrderBy方法。注意对于OrderBy的lambda表达不用像Where方法那样需要条件判断值是否为真或假。它只需返回属性一个属性,参见示例3-5.

注:当方法签名要求谓词时,像Where方法,它要求表达式返回一个布尔值。否则,lambda表达式只需要成为一个函数,像OrderBy方法。你会看到在VB中,所有方法的签名都称之为函数。C#方法则在方法中特别提到要求返回布尔值的表达式的谓词。你可以在MSDN文档的话题"支持与不被支持的方法(LINQ to Entities)"中查看LINQ to Entities各种方法的签名。

虽然在混合方法中,你可以容易地使用相同名称的变量,该变量不代表相同的实例。在前面的LINQ查询中,我给了变量不同的名称,以突出编译器如何评估查询。

一次评估一个方法不是说一次执行一个查询。LINQ to Entities将每次评估一个方法,然后创建基于整个方法的SQL查询,除非你使用方法表明它必须在客户端执行。它不会将每个方法分开执行。

这儿有一个从之前的查询中生成的T-SQL:

使用查询构造方法和实体SQL查询

在实体SQL中也可以使用方法语法,虽然只有有限的几个方法:13个,事实上,还包括Where和Select。这些方法被称为查询构造方法。查询构建方法像他们的名称建议的那样:使用正确的实体SQL表达式创建对象查询(ObjectQuery)。

虽然查询构造器可能看起来像某些LINQ方法,他们绝对不同。当你使用基于参数表达式(它将包括或者LINQ查询的lambda表达式,或者实体SQL表达式)的查询构造方法时, 编译器可以辨别。

注:在学习不同的查询方法时,因为到目前为止只探索了WHERE和SELECT,我们暂时不列出方法和运算符,在后面的章节中我们再列举更多的查询方法。

示例3-6展示了最近的查询,它使用了实体SQL作为方法参数。

考虑这些表达式时最常见的问题是"它来自于哪里?"。它是控制变量的默认别名。因为你必须与其它查询一起,就没有机会定义控制变量,尽管你是可以为内嵌的查询定义变量,如我们在示例3-8中看到的。

在调试时,你可以检查contacts对象查询的CommandText属性,看看查询构造器确实为你创建了如示例3-7中的实体SQL。它可能比你自己写过的查询略显复杂。这是查询构造器必须流利的结果。此外,它没有在表达式中指定EntityContainer的名称,它是你在构造实体SQL中无法避免的。

使用实体SQl和有着lambda表达式的LINQ方法创建查询构造方法之间有一个非常有趣的差别,那就是实体表达式移除了VB和C#之间语法差异的担心。

不管你使用的是LINQ谓词,还是实体SQL谓词,在编译期EF通过查看谓词能决定选择哪个查询编译路径。

如你在示例3-8中看到的,你还可以联合查询构造方法。EF控制变量对所有新的OjbectQuery实例默认都是一样的。然而,当你拥有了ObjectQuery实例时,你可以改变控制变量的名称,通过设计名称的属性。在那儿你可以持续组合如示例3-8所示的查询。

前面的示例演示了另一个特性,叫做可组合的查询。定义了一个查询,然后另一个查询基于此编写。第一个查询不会单独执行。它会被编译到第二个查询contacts中。当contacts查询最终被执行时,组合查询被EF编译,然后发往数据库。

我要回帖

更多关于 北京一卡通绑定实体卡 的文章

 

随机推荐