Entity Framework 6 Recipes 2nd Edition(10-1)译->非Code Frist方式返回一个实体集合
存储过程
存储过程一直存在于任何一种关系型数据库中,如微软的SQL Server.存储过程是包含在数据库中的一些代码,通常为数据执行一些操作,它能为数据密集型计算提高性能,也能执行一些为业务逻辑. 当你使用数据的时候,有时你会通过存储过程来获取它们.
在本章, 我们探讨一些EF在使用存储过程时,需要关注的地方。我们在本书的其它章节也使用了存储过程, 但通常都是context为执行插入、更新和删除动作。
在本章,我们将为你展示多种使用存储过程的方式。
10-1. 非Code Frist方式返回一个实体集合
问题
想用非Code Frist方式从存储过程里取得一个实体集合
解决方案
Code second (我把它译为非Code Frist)是参照 Code-First 技术,为一个已经存在的数据库建模的方式
我们假设有一个 POCO模型,如Listing 10-1所示:
Listing 10-1. The Customer POCO Model
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public string Company { get; set; }
public string ContactTitle { get; set; }
}
我们已经设置好了DbContext子类和Customer 实体集,如Listing 10-2所示:
Listing 10-2. The DbContext Subclass for Customer Entities
public class EF6RecipesContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public EF6RecipesContext() : base("name=EF6CodeFirstRecipesContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Types<Customer>()
.Configure(c =>
{
c.HasKey(cust => cust.CustomerId);
c.Property(cust => cust.CustomerId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
c.Property(cust => cust.Name)
.HasMaxLength(50);
c.Property(cust => cust.Company)
.HasMaxLength(50);
c.Property(cust => cust.ContactTitle)
.HasMaxLength(50);
c.ToTable("Customer", "Chapter10");
});
}
}
在数据库中,我们已经定义了如Listing 10-3所示的存储过程,该存储过程根据公司名称和客户标题返回符合条件的 customer
Listing 10-3. GetCustomers Returns All of the Customers with the Given Title in the Given Company.
create procedure Chapter10.GetCustomers
(@Company varchar(50),@ContactTitle varchar(50))
as
begin
select * from
chapter10.Customer where
(@Company is null or Company = @Company) and
(@ContactTitle is null or ContactTitle = @ContactTitle)
End
为了在方法中使用 GetCustomers 存储过程,操作如下:
1. 在DbContext 子类中创建一个公开的方法(命名为GetCustomers),它接受两个string参数,并返回Customer集合, 如 Listing 10-4所示.
Listing 10-4. A New Method to Return a Collection of Customer Objects
public ICollection<Customer> GetCustomers(string company, string contactTitle)
{
throw new NotImplementedException();
}
2.接下来实现这个GetCustomers() 方法,它调用DbContext.Database的SqlQuery方法DbContext.Database
如Listing 10-5所示.
Listing 10-5. DbContext Subclass with GetCustomers() Implementation
public class EF6RecipesContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public EF6RecipesContext() : base("name=EF6CodeFirstRecipesContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Types<Customer>()
.Configure(c =>
{
c.HasKey(cust => cust.CustomerId);
c.Property(cust => cust.CustomerId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
c.Property(cust => cust.Name)
.HasMaxLength(50);
c.Property(cust => cust.Company)
.HasMaxLength(50);
c.Property(cust => cust.ContactTitle)
.HasMaxLength(50);
c.ToTable("Customer", "Chapter10");
});
}
public ICollection<Customer> GetCustomers(string company, string contactTitle)
{
return Database.SqlQuery<Customer>( "EXEC Chapter10.GetCustomers @Company,
@ContactTitle"
, new SqlParameter("Company", company)
, new SqlParameter("ContactTitle", contactTitle))
.ToList();
}
}
3.接下来的这个代码段Listing 10-6 就是调用GetCustomers存储过程.
Listing 10-6. Querying the Model with the GetCustomers Stored Procedure via the GetCustomers()
Method
//插入一些Customer,让存储过程查询.
using (var context = new EF6RecipesContext())
{
var c1 = new Customer {Name = "Robin Steele", Company = "GoShopNow.com",
ContactTitle="CEO"};
var c2 = new Customer {Name = "Orin Torrey", Company = "GoShopNow.com",
ContactTitle="Sales Manager"};
var c3 = new Customer {Name = "Robert Lancaster", Company = "GoShopNow.com",
ContactTitle = "Sales Manager"};
var c4 = new Customer { Name = "Julie Stevens", Company = "GoShopNow.com",
ContactTitle = "Sales Manager" };
context.Customers.Add(c1);
context.Customers.Add(c2);
context.Customers.Add(c3);
context.Customers.Add(c4);
context.SaveChanges();
}
using (var context = new EF6RecipesContext())
{
var allCustomers = context.GetCustomers("GoShopNow.com", "Sales Manager");
Console.WriteLine("Customers that are Sales Managers at GoShopNow.com");
foreach (var c in allCustomers)
{
Console.WriteLine("Customer: {0}", c.Name);
}
}
以下Listing 10-6是控制台输出结果:
============================================================================================
Customers that are Sales Managers at GoShopNow.com
Customer: Orin Torrey
Customer: Robert Lancaster
Customer: Julie Stevens
=============================================================
它是如何工作的?
为了能接收数据库中的存储过程里返回的实体集合,我们在DbContext子类中实现了 GetCustomers()方法,该方法用DbContext.Database.SqlQuery<T>() 来执行存储过程 GetCustomers(它的定义见Listing 10-3). SqlQuery() 方法能用来执行返回一个结果集的 DML(数据操纵语言)语句. 该方法接收一个SQL语句的字符串。SqlQuery<T>() 泛型方法返回一个开发人员指定的强类型的实体集。
Entity Framework 6 Recipes 2nd Edition(10-1)译->非Code Frist方式返回一个实体集合的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪
9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...
- Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询
问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...
- Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体
问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...
- Entity Framework 6 Recipes 2nd Edition(13-3)译 -> 为一个只读的访问获取实体
问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种 ...
- Entity Framework 6 Recipes 2nd Edition(13-5)译 -> 使POCO的修改追踪更高
问题 你正在使用POCO,你想提高修改跟踪的性能,同时使内存消耗更少.另外,你想通过EF的CodeFirst方式来实现. 解决方案 假设你有一个关于Account(帐户)和相关的Payments(支付 ...
- Entity Framework 6 Recipes 2nd Edition(13-8)译 -> 把昂贵的属性移到其它实体
问题 你想把一个昂贵的属性移到另一个实体,这样你就可以延迟加载当前这个实体.对于一个加载昂贵的而且很少用到的属性尤其有用. 解决方案 模型和上一节(Recipes 13-7)的一致,如Figure13 ...
随机推荐
- 对抗密码破解 —— Web 前端慢 Hash
(更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...
- lua 学习笔记(1)
一.lua函数赋值与函数调用 在lua中函数名也是作为一种变量出现的,即函数和所有其他值一样都是匿名的,当要使用某个函数时,需要将该函数赋值给一个变量,这样在函数块的其他地方就可以通过 ...
- 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载
title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...
- MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句
第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...
- 图解CSS3制作圆环形进度条的实例教程
圆环形进度条制作的基本思想还是画出基本的弧线图形,然后CSS3中我们可以控制其旋转来串联基本图形,制造出部分消失的效果,下面就来带大家学习图解CSS3制作圆环形进度条的实例教程 首先,当有人说你能不能 ...
- Flex 布局教程:实例篇
该教程整理自 阮一峰Flexible教程 今天介绍常见布局的Flex写法.你会看到,不管是什么布局,Flex往往都可以几行命令搞定. 我的主要参考资料是Landon Schropp的文章和Solved ...
- arcgis api for js入门开发系列七图层控制(含源代码)
上一篇实现了demo的地图分屏对比模块,本篇新增图层控制模块,截图如下(源代码见文章底部): 图层控制模块实现的思路如下: 1.在地图配置文件map.config.js里面配置图层目录树节点信息,作为 ...
- H3 BPM让天下没有难用的流程之技术体系
一.技术架构 H3 BPM 基于微软.NET 技术架构,采用C#语言开发,以高开放.高扩展.高性能为核心准则,遵循分层的设计原理,结合最新的B/S 以及智能手机应用开发技术研发的. 图:H3 BPM ...
- SharePoint2016安装的过程的”Microsoft.SharePoint.Upgrade.SPUpgradeException”错误解决方法
前提 在windows server 2012的服务器上运行安装sharepoint2016出现如下错误: Could not load file or assembly ‘Microsoft.Dat ...
- 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...