Entity Framework 6 Recipes 2nd Edition(10-6)译 -> TPT继承模型中使用存储过程
10-6. TPT继承模型中使用存储过程
问题
想在一个TPT继承模型中使用存储过程
解决方案
假设已有如Figure 10-6所示模型. 在模型里, Magazine(杂志) and DVD继承于基类Media(媒体,译注:示例数据库中的表名其实为:Medium,你在做例子或是下文代码出现Medium,请自己辨别). 在数据库里,每个实体各自有一个表,我们用TPT方式为为些表建模.我们想用一个存储过程从数据库中为这些模型来获取数据。

Figure 10-6. A model using Table per Type inheritance. The model represents some information about magazines and DVDs
===================================================================
■■提示:如果需要复习TPT模式和它的性能影响?请查阅第2章的2-8小节
========================================================================================
接下来创建存储过程及使用它获取实体
1.在数据库中创建如 Listing 10-15所示的存储过程.
Listing 10-15. The GetAllMedia Stored Procedure That Returns a Rowset with a Discriminator Column
create procedure [Chapter10].[GetAllMedia]
as
begin
select m.MediaId,c.Title,m.PublicationDate, null PlayTime,'Magazine' MediaType
from chapter10.Media c join chapter10.Magazine m on c.MediaId = m.MediaId
union
select d.MediaId,c.Title,null,d.PlayTime,'DVD'
from chapter10.Media c join chapter10.DVD d on c.MediaId = d.MediaId
end
2.右击模型设计视图,选择 “从数据库中更新模型”,选择存储过程GetAllMedia.点击“完成”
3. ( 译注:我的环境是win10+vs2013+ef6.1.3,是不需要这步的,第1步已经把这步也完成了,只是最后的“返回以下内容的集合”必须修改一下)右击模型的设计视图, 选择“新增“ ➤ 函数导入. 从“存储过程/函数名称”下拉框中选择GetAllMedia. 在“函数导入名称“文本框中输入:GetAllMedia. 这个就是在模型中的方法名称.在“返回以下内容的集合”里勾选“实体”,在下拉框里选择Media.单击“确定”.将会创建<FunctionImportMapping>框架.
4. 右击 .edmx 文件, 选择“打开方式” ➤ XML Editor.编辑.edmx文件的mapping 小节下
的<FunctionImportMapping> 标签,用 Listing 10-16所示代码去匹配(因为像EF6RecipesModel的命名与你的例子可能不同).它会映射被存储过程返回的列与Media类型的实体的属性。
Listing 10-16. This FunctionImportMapping Conditionally Maps the Returned Rows to Either the
Magazine or the DVD Entity.
<FunctionImportMapping FunctionImportName="GetAllMedia" FunctionName="EF6RecipesModel.Store.GetAllMedia">
<ResultMapping>
<EntityTypeMapping TypeName="EF6RecipesModel.Magazine">
<ScalarProperty ColumnName="PublicationDate" Name="PublicationDate"/>
<Condition ColumnName="MediaType" Value="Magazine"/>
</EntityTypeMapping>
<EntityTypeMapping TypeName="EF6RecipesModel.DVD">
<ScalarProperty ColumnName="PlayTime" Name="PlayTime"/>
<Condition ColumnName="MediaType" Value="DVD"/>
</EntityTypeMapping>
</ResultMapping>
</FunctionImportMapping>
5. 接下来用Listing 10-17所示的代码通过GetAllMedia()方法调用存储过程GetAllMedia
Listing 10-17. Using the GetAllMedia Stored Procedure via the GetAllMedia() Method
static void Main(string[] args)
{
using (var context = new EFRecipesEntities1006())
{
context.Media.Add(new Magazine
{
Title = "Field and Stream",
PublicationDate = DateTime.Parse("6/12/1945")
});
context.Media.Add(new Magazine
{
Title = "National Geographic",
PublicationDate = DateTime.Parse("7/15/1976")
});
context.Media.Add(new DVD
{
Title = "Harmony Road",
PlayTime = "2 hours, 30 minutes"
});
context.SaveChanges();
}
using (var context = new EFRecipesEntities1006())
{
var allMedia = context.GetAllMedia();
Console.WriteLine("All Media");
Console.WriteLine("=========");
foreach (var m in allMedia)
{
if (m is Magazine)
Console.WriteLine("{0} Published: {1}", m.Title,
((Magazine)m).PublicationDate.ToShortDateString());
else if (m is DVD)
Console.WriteLine("{0} Play Time: {1}", m.Title, ((DVD)m).PlayTime);
}
}
Console.WriteLine("\npress any key to exit...");
Console.ReadKey();
}
输出结果如下面的Listing 10-17:
===================================================================
All Media
=========
Field and Stream Published: 6/12/1945
National Geographic Published: 7/15/1976
Harmony Road Play Time: 2 hours, 30 minutes
===========================================
它是如何工作的?
该解决方案有两个关键点:鉴别列注入到结果集中和用条件映射结果实体.
===================================================================
■■注意:鉴别列是用来指定对象类型的数据库元数据列的记录.
========================================================================================
10-15所示的存储过程是把从 Magazine and取得的记录与从 DVD表取得的记录联合起来的表,然后把这个表注入到Magazine或DVD等媒体类型的鉴别列中.我们为每个select,我们都连接表示模型基类的 Media 表, 为了包含Title 列. 所有从这三个表来的记录,都包含在结果集中,并且含有具体从某个表来的标记.根据记录的标记(Magazine或DVD),我们把它们分别映射到Magazine 或DVD 实体. 这个操作在<FunctionImportMapping>节里完成,.
当我们添加函数导入时添加了调用GetAllMedia存储过程的方法GetAllMedia(),在Listing 10-17里,我们调用该方法.之后,整个对象图被继承结构完整地实例化。我们遍历这个对象集合,交替得打印出Magazine 和DVD 实体.
Entity Framework 6 Recipes 2nd Edition(10-6)译 -> TPT继承模型中使用存储过程的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(10-7)译 -> TPH继承模型中使用存储过程
10-7. TPH继承模型中使用存储过程 问题 用一个存储过程来填充TPH继承模型的实体 解决方案 假设已有如Figure 10-7所示模型. 我们有两个派生实体: Instructor(教员)和St ...
- 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-1)译 -> 优化TPT继承模型的查询
问题 你想提高在一个TPT继承模型里的查询 解决方案 让我们假设有一个简单的TPT继承模型,如图Figure 13-1 Figure 13-1. A simple Table per Type inh ...
- 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(13-2)译 -> 用实体键获取一个单独的实体
问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...
- Entity Framework 6 Recipes 2nd Edition(13-3)译 -> 为一个只读的访问获取实体
问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种 ...
随机推荐
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- IdentityServer4 使用OpenID Connect添加用户身份验证
使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...
- Java程序:从命令行接收多个数字,求和并输出结果
一.设计思想:由于命令行接收的是字符串类型,因此应先将字符串类型转化为整型或其他字符型,然后利用for循环求和并输出结果 二.程序流程图: 三.源程序代码: //王荣荣 2016/9/23 ...
- Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题
现互联网公司后端架构常用到Spring+SpringMVC+MyBatis,通过Maven来构建.通过学习,我已经掌握了基本的搭建过程,写下基础文章为而后的深入学习奠定基础. 首先说一下这篇文章的主要 ...
- Android Studio快捷键
一.android studio 默认快捷键 刚开始接触一款开发软件,想必很想了解它的快捷方式,这会对你的编程起到很好的帮助,提高工作效率,接下来给你介绍下Android Studio一些常用的快 ...
- TabLayout + ViewPager
一.实现思路 1.在build.gradle中添加依赖,例如: compile 'com.android.support:support-v4:23.4.0'compile 'com.android. ...
- 敏捷转型历程 - Sprint3 Planning
我: Tech Leader 团队:团队成员分布在两个城市,我所在的城市包括我有4个成员,另外一个城市包括SM有7个成员.另外由于我们的BA离职了,我暂代IT 的PO 职位.PM和我在一个城市,但他不 ...
- JAVA 设计模式之策略模式
定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过 ...
- Linux实战教学笔记01:计算机硬件组成与基本原理
标签(空格分隔): Linux实战教学笔记 第1章 如何学习Linux 要想学好任何一门学问,不仅要眼睛看,耳朵听,还要动手记,勤思考,多交流甚至尝试着去教会别人. 第2章 服务器 2.1 运维的基本 ...
- 【Star CCM+实例】开发一个简单的计算流程.md
流程开发在CAE过程中处于非常重要的地位. 主要的作用可能包括: 将一些经过验证的模型隐藏在流程中,提高仿真的可靠性 将流程封装成更友好的界面,降低软件的学习周期 流程开发实际上需要做非常多的工作,尤 ...