博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework 学习初级篇3-- LINQ TO Entities
阅读量:5823 次
发布时间:2019-06-18

本文共 5129 字,大约阅读时间需要 17 分钟。

  

LINQ 技术(即 LINQ to Entities)使开发人员能够通过使用 LINQ 表达式和 LINQ 标准查询运算符,直接从开发环境中针对 实体框架对象上下文创建灵活的强类型查询。LINQ to Entities 查询使用对象服务基础结构。ObjectContext 类是作为 CLR 对象与 实体数据模型 进行交互的主要类。开发人员通过 ObjectContext 构造泛型 ObjectQuery 实例。ObjectQuery 泛型类表示一个查询,此查询返回一个由类型化实体组成的实例或集合。返回的实体对象可供更新并位于对象上下文中。以下是创建和执行 LINQ to Entities 查询的过程:

1.     从 ObjectContext 构造 ObjectQuery 实例。

2.     通过使用 ObjectQuery 实例在 C# 或 Visual Basic 中编写 LINQ to Entities 查询。

3.     将 LINQ 标准查询运算符和表达式将转换为命令目录树。

4.     对数据源执行命令目录树表示形式的查询。执行过程中在数据源上引发的任何异常都将直接向上传递到客户端。

5.     将查询结果返回到客户端。

 

ContractedBlock.gif
ExpandedBlockStart.gif
Code
一、Linq To Entities简单查询
下面将介绍简单的Linq To Entities查询,相关的查询语法可以使用基于表达式或基于方法的语法。本节使用的TestDriver.Net配合Nunit2.4进行测试。
1
, 投影
代码如下:
using
 System;
using
 System.Collections.Generic;
using
 System.Linq;
using
 System.Data.Objects;
using
 NUnit.Framework;
namespace
 NorthWindModel
{
    [TestFixture]
    
public
 
class
 TestEFModel
    {
        [Test]
        
public
 
void
 Select()
        {
            
using
 (var edm 
=
 
new
 NorthwindEntities())
            {
                
//
基于表达式的查询语法
                ObjectQuery
<
Customers
>
 customers 
=
 edm.Customers;
                IQueryable
<
Customers
>
 cust1 
=
 from c 
in
 customers
                                              select c;
                Assert.Greater(cust1.Count(), 
0
);
                
//
使用ObjectQuery类的ToTraceString()方法显示查询SQL语句
                Console.WriteLine(customers.ToTraceString());
 
 
            }
        }
    }
}
输出:
SELECT 
[Extent1].[CustomerID] AS [CustomerID], 
[Extent1].[CompanyName] AS [CompanyName], 
[Extent1].[ContactName] AS [ContactName], 
[Extent1].[ContactTitle] AS [ContactTitle], 
[Extent1].[Address] AS [Address], 
[Extent1].[City] AS [City], 
[Extent1].[Region] AS [Region], 
[Extent1].[PostalCode] AS [PostalCode], 
[Extent1].[Country] AS [Country], 
[Extent1].[Phone] AS [Phone], 
[Extent1].[Fax] AS [Fax]
FROM [dbo].[Customers] AS [Extent1]
 
1
 passed, 
0
 failed, 
0
 skipped, took 
11.00
 seconds (NUnit 
2.4
).
在上面的输出内容中,可以看到使用了ToTraceString()方法来输出具体的SQL语句。同时Nunit也输出相关的测试情况,请注意查询所花费的时间,以便我们进行查询速度的分析比较。
2
, 条件限制
using
 (var edm 
=
 
new
 NorthwindEntities())
{
    
//
基于表达式的查询语法
    ObjectQuery
<
Customers
>
 customers 
=
 edm.Customers;
    IQueryable
<
Customers
>
 cust1 
=
 from c 
in
 customers
                                  
where
 c.CustomerID 
==
 
"
ALFKI
"
                                  select c;
   
    Assert.AreEqual(cust1.Count(), 
1
);
    
foreach
 (var c 
in
 cust1)
        Console.WriteLine(
"
CustomerID={0}
"
, c.CustomerID);
               
    
//
基于方法的查询语法
    var cust2 
=
 edm.Customers.Where(c 
=>
 c.CustomerID 
==
 
"
ALFKI
"
);
    Assert.AreEqual(cust2.Count(), 
1
);
    
foreach
 (var c 
in
 cust2)
          Console.WriteLine(
"
CustomerID={0}
"
, c.CustomerID);
 
}
3
, 排序和分页
在使用Skip和Take方法实现分页时,必须先对数据进行排序,否则将会抛异常。
using
 (var edm 
=
 
new
 NorthwindEntities())
 {
//
基于表达式的查询语法
         ObjectQuery
<
Customers
>
 customers 
=
 edm.Customers;
         IQueryable
<
Customers
>
 cust10 
=
 (from c 
in
 customers
                                         orderby c.CustomerID
                                         select c).Skip(
0
).Take(
10
);
 
          Assert.AreEqual(cust10.Count(), 
10
);
          
foreach
 (var c 
in
 cust10)
              Console.WriteLine(
"
CustomerID={0}
"
, c.CustomerID);
    
//
基于方法的查询语法
    var cust 
=
 edm.Customers.OrderBy(c 
=>
 c.CustomerID).Skip(
0
).Take(
10
);
    Assert.AreEqual(cust.Count(), 
10
);
    
foreach
 (var c 
in
 cust)
        Console.WriteLine(
"
CustomerID={0}
"
, c.CustomerID);
 }
4
, 聚合
可使用的聚合运算符有Average、Count、Max、Min 和 Sum。
using
 (var edm 
=
 
new
 NorthwindEntities())
   {
       var maxuprice 
=
 edm.Products.Max(p 
=>
 p.UnitPrice);
       Console.WriteLine(maxuprice.Value);
 }
5
, 连接
可以的连接有Join 和 GroupJoin 方法。GroupJoin组联接等效于左外部联接,它返回第一个(左侧)数据源的每个元素(即使其他数据源中没有关联元素)。
using
 (var edm 
=
 
new
 NorthwindEntities())
    {
       var query 
=
 from d 
in
 edm.Order_Details
                   join order 
in
 edm.Orders
                   on d.OrderID equals order.OrderID
                   select 
new
                    {
                        OrderId 
=
 order.OrderID,
                        ProductId 
=
 d.ProductID,
                        UnitPrice 
=
 d.UnitPrice
                     };
        
foreach
 (var q 
in
 query)
         Console.WriteLine(
"
{0},{1},{2}
"
,q.OrderId,q.ProductId,q.UnitPrice);
}
其他一些方法等就不多说了,和Linq to SQL 基本上是一样的。
二、LINQ to Entities 查询注意事项
l           排序信息丢失
如果在排序操作之后执行了任何其他操作,则不能保证这些附加操作中会保留排序结果。这些操作包括 Select 和 Where 等。另外,采用表达式作为输入参数的 First 和 FirstOrDefault 方法不保留顺序。
如下代码:并不能达到反序排序的效果
using
 (var edm 
=
 
new
 NorthwindEntities())
{
     IQueryable
<
Customers
>
 cc 
=
 edm.Customers.OrderByDescending(c 
=>
 c.CustomerID).Where(c 
=>
 c.Region 
!=
 
null
).Select(c 
=>
 c);
     
foreach
 (var c 
in
 cc)
          Console.WriteLine(c.CustomerID);
}
l           不支持无符号整数
由于 实体框架不支持无符号整数,因此不支持在 LINQ to Entities 查询中指定无符号整数类型。如果指定无符号整数,则在查询表达式转换过程中会引发 NotSupportedException异常,并显示无法创建类型为“结束类型”的常量值。此上下文仅支持基元类型(“例如 Int32、String 和 Guid”)。
如下将会报异常的代码:
using
 (var edm 
=
 
new
 NorthwindEntities())
 {
      
uint
 id 
=
 UInt32.Parse(
"
123
"
);
      IQueryable
<
string
>
 produt 
=
 from p 
in
 edm.Products
                                  
where
 p.UnitPrice 
==
 id
                                  select p.ProductName;
      
foreach
 (
string
 name 
in
 produt)
            Console.WriteLine(name);
}
上面的代码中,由于id是uint而不是Int32,String,Guid的标量类型,所以在执行到where p.UnitPrice 
==
id这个地方时,会报异常。
l           不支持引用非标量闭包
不支持在查询中引用非标量闭包(如实体)。在执行这类查询时,会引发 NotSupportedException 异常,并显示消息“无法创建类型为“结束类型”的常量值。此上下文中仅支持基元类型(‘如 Int32、String 和 Guid’)
如下将会报异常的代码:
using
 (var edm 
=
 
new
 NorthwindEntities())
 {
        Customers customer 
=
 edm.Customers.FirstOrDefault();
        IQueryable
<
string
>
 cc 
=
 from c 
in
 edm.Customers
                                
where
 c 
==
 customer
                                select c.ContactName;
         
foreach
 (
string
 name 
in
 cc)
               Console.WriteLine(name);
}
上面的代码中,由于customer是引用类型而不是Int32,String,Guid的标量类型,所以在执行到where c
==
customer这个地方时,会报异常。
好.

 

版权说明

  如果标题未标有<转载、转>等字则属于作者原创,欢迎转载,其版权归作者和博客园共有。

  作      者:温景良
  文章出处:  或 

分类:
+加关注
0
0
上一篇:
下一篇:
posted @ 2009-05-25 15:15 Views( 267) Comments( 0)
 
最新IT新闻:
·
·
·
·
·
»
最新知识库文章:
·
·
·
·
·
»

公告

本文转自 博客园博客,原文链接: 如需转载请自行联系原作者
 
 
你可能感兴趣的文章
Linux 环境下 PHP 扩展的编译与安装 以 mysqli 为例
查看>>
浮点数内存如何存储的
查看>>
贪吃蛇
查看>>
EventSystem
查看>>
用WINSOCK API实现同步非阻塞方式的网络通讯
查看>>
玩一玩博客,嘿嘿
查看>>
P1352 没有上司的舞会
查看>>
ios11文件夹
查看>>
【HLOJ 559】好朋友的题
查看>>
Electric Fence(皮克定理)
查看>>
nvl 在mysql中如何处理
查看>>
MyEclipse 快捷键
查看>>
快速傅里叶变换FFT
查看>>
大数据常用基本算法
查看>>
JavaScript学习笔记(十三)——生成器(generator)
查看>>
hibernate保存失败
查看>>
MySQL增量订阅&消费组件Canal POC
查看>>
Sqlite多线程
查看>>
数据结构-时间复杂度
查看>>
对象与字符串相互转换
查看>>