Entity Framework 6 Recipes 2nd Edition(10-5)译 -> 在存储模型中使用自定义函数
10-5. 在存储模型中使用自定义函数
问题
想在模型中使用自定义函数,而不是存储过程.
解决方案
假设我们数据库里有成员(members)和他们已经发送的信息(messages) 关系数据表,如Figure 10-4 所示:

Figure 10-4. A simple database of members and their messages
可能有这种情况,我们不允许入门级的程序员在数据库中创建存储过程,然而,又想封装members和他们发送的messages条数最多的业务逻辑,这个时候我们可以在模型中使用自定义函数。
我们的模型就如Figure 10-5所示:

Figure 10-5. The model for members and their messages
接下来在模型中定义函数To define the custom function in the storage model, do the following:
1.右击.edmx 文件,选择“打开方式” ➤ XML (文本)编辑器. 这样就会把.edmx 文件肜XML编辑器的方式打开.把 Listing 10-13里的代码添加到<Schema> 元素里(译注:你可能会发现有两个这样的元素,放在<edmx:StorageModels>里的那个就可以). 这个就是函数的定义.
Listing 10-13. The Definition of the Custom Function MembersWithTheMostMessages
<Function Name="MembersWithTheMostMessages" IsComposable="false">
<CommandText>
select m.*
from chapter10.member m
join
(
select msg.MemberId, count(msg.MessageId) as MessageCount
from chapter10.message msg where datesent = @datesent
group by msg.MemberId
) temp on m.MemberId = temp.MemberId
order by temp.MessageCount desc
</CommandText>
<Parameter Name="datesent" Type="datetime" />
</Function>
2. 打开.edmx 文件的设计视图.右击设计视图,选择“新增” ➤ 函数导入.在对话框的“存储过程/函数名称”下选择MembersWithTheMostMessages,在“函数导入名称”方框框里输入MembersWithTheMostMessages., 在“返回以下内容的集合”里选择“实体”,在后面下拉框中选择Member. 单击“确定”.
3. 接下来在Listing 10-14 代码里通过使用 MembersWithTheMostMessages() 方法,来调用自定义函数MembersWithTheMostMessages
Listing 10-14. 通过MembersWithTheMostMessages()调用自定义函数MembersWithTheMostMessages
class Program
{
static void Main(string[] args)
{
DateTime today = DateTime.Parse("5/7/2013");
using (var context = new EFRecipesEntities1005())
{
var mem1 = new Member { Name = "Jill Robertson" };
var mem2 = new Member { Name = "Steven Rhodes" };
mem1.Messages.Add(new Message
{
DateSent = today,
MessageBody = "Hello Jim",
Subject = "Hello"
});
mem1.Messages.Add(new Message
{
DateSent = today,
MessageBody = "Wonderful weather!",
Subject = "Weather"
});
mem1.Messages.Add(new Message
{
DateSent = today,
MessageBody = "Meet me for lunch",
Subject = "Lunch plans"
});
mem2.Messages.Add(new Message
{
DateSent = today,
MessageBody = "Going to class today?",
Subject = "What's up?"
});
context.Members.Add(mem1);
context.Members.Add(mem2);
context.SaveChanges();
}
using (var context = new EFRecipesEntities1005())
{
Console.WriteLine("Members by message count for {0}",
today.ToShortDateString());
var members = context.MembersWithTheMostMessages(today);
foreach (var member in members)
{
Console.WriteLine("Member: {0}", member.Name);
}
}
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
}
如下Listing 10-14所示是输出结果:
===================================================================
Members by message count for 5/7/2013
Member: Jill Robertson
Member: Steven Rhodes
===========================================
它是如何工作的?
一个自定义函数不同于模型定义的函数(见 Chapter 11) ,因为自定义函数是定义在存储模型中。这样使自定义函数就像传统的自义在数据库中的存储过程。如果说存储过程好比是在存储模型中定义一个“虚拟”的表,那么自定义函数就像是定义在存储模型中的一个“虚拟”的存储过程。
一些EF团队把它称为“自然函数”然后微软的团队用“自定义函数”,所以我们也用这个名称。
Listing 10-13里的代码定义我们的自定义函数.我们用XML编辑器把它放到.edmx文件存储模型节点(<edmx:StorageModels>)里。
注意:如果你用“从数据库更新模型”向导来更新模型,那么该向导会重写这个节点。所以在用向导前,请小心保存你在存储模型里所做的修改。
就像之前小节里使用存储过程一样,我们用“函数导入”向导来映射用户自定义函数到一个方法里。它设定了方法名,返回类型。在本例中,自定义函数返回Member实体集。
Listing 10-14里的代码,展示了用MembersWithTheMostMessages() 方法来调用自定义函数.这个方式与我们调用存储过程是一样的。
自定义函数适用于以下几种情况:
l 你没有创建存储过程的权限
l 你想把数据库和代码分开来管理.你可以使用自定义函数,而不用在数据库创建存储过程
l 当数据库中的存储过程的参数与你的实体不兼容时,你可以使用自定义函数,使用一个抽象层来来处理存储过程参数与你实体属性之间的类型转换。
Entity Framework 6 Recipes 2nd Edition(10-5)译 -> 在存储模型中使用自定义函数的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- 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(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- 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(11-9)译 -> 在LINQ中使用规范函数
11-9. 在LINQ中使用规范函数 问题 想在一个LINQ查询中使用规范函数 解决方案 假设我们已经有一个影片租赁(MovieRental )实体,它保存某个影片什么时候租出及还回来,以及滞纳金等, ...
- 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(支付 ...
随机推荐
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
- 搞个这样的APP要多久?
这是一个“如有雷同,纯属巧合”的故事,外加一些废话,大家请勿对号入座.开始了…… 我有些尴尬地拿着水杯,正对面坐着来访的王总,他是在别处打拼的人,这几年据说收获颇丰,见移动互联网如火如荼,自然也想着要 ...
- TODO:Laravel 内置简单登录
TODO:Laravel 内置简单登录 1. 激活Laravel的Auth系统Laravel 利用 PHP 的新特性 trait 内置了非常完善好用的简单用户登录注册功能,适合一些不需要复杂用户权限管 ...
- 在Sublime Text 3上安装代码格式化插件CodeFormatter
1.了解CodeFormatter插件 在Sublime Text 3中编写代码,为了能让我们的代码格式变得漂亮整洁,需要一个能自动格式代码的插件.这里发现CodeFormatter插件不错,它能支持 ...
- EventBus实现activity跟fragment交互数据
最近老是听到技术群里面有人提出需求,activity跟fragment交互数据,或者从一个activity跳转到另外一个activity的fragment,所以我给大家介绍一个开源项目,EventBu ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
集群概念介绍(一)) 白宁超 2015年7月16日 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习 ...
- ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器
原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...
- 【一起学OpenFOAM】系列由来
1 为什么要学习OpenFOAM 掐指算起来,接触CFD也差不多有十个年头了,其间一直使用的商用CFD软件,有Fluent.CFX.StarCCM+等,这些商用软件各有其优缺点,都能较好的解决常规的工 ...
- linux常用命令(3)mkdir命令
mkdir命令1 命令格式:mkdir [选项]目录名2 命令功能:通过 mkdir 命令可以实现在指定位置创建以 DirName(指定的文件名)命名的文件夹或目录.要创建文件夹或目录的用户必须对所创 ...