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)译 -> 在存储模型中使用自定义函数的更多相关文章

  1. Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新

    因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...

  2. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  3. Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪

    9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...

  4. Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体

    第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...

  5. Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询

    问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...

  6. Entity Framework 6 Recipes 2nd Edition(11-9)译 -> 在LINQ中使用规范函数

    11-9. 在LINQ中使用规范函数 问题 想在一个LINQ查询中使用规范函数 解决方案 假设我们已经有一个影片租赁(MovieRental )实体,它保存某个影片什么时候租出及还回来,以及滞纳金等, ...

  7. Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体

    问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...

  8. Entity Framework 6 Recipes 2nd Edition(13-3)译 -> 为一个只读的访问获取实体

    问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种 ...

  9. Entity Framework 6 Recipes 2nd Edition(13-5)译 -> 使POCO的修改追踪更高

    问题 你正在使用POCO,你想提高修改跟踪的性能,同时使内存消耗更少.另外,你想通过EF的CodeFirst方式来实现. 解决方案 假设你有一个关于Account(帐户)和相关的Payments(支付 ...

随机推荐

  1. 如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  2. python与c互相调用

    虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中 ...

  3. 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇

    最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...

  4. 自定义搭建PHP开发环境

    学习了一段时间php了,因为之前是刚接触php,所以用的是集成安装包(wamp).现在想进一步了解apache.mysql.php之间的关系以及提升自己所以进行自定义搭建PHP开发环境.废话不多说,请 ...

  5. BPM配置故事之案例12-触发另外流程

    还记得阿海么,对就是之前的那个采购员,他又有了些意见. 阿海:小明,你看现在的流程让大家都这么方便,能不能帮个忙让我也轻松点啊-- 小明:--你有什么麻烦,现在不是已经各个部门自己提交申请了嘛? 阿海 ...

  6. 编写一个通用的Makefile文件

    1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...

  7. java 泛型

    1.Student stu =tool.getObj();右边得到的是Object类型,需要向下转型,强转换. 2. 3. 4.泛型方法不能被静态修饰这样写 5.如果想定义定义静态泛型方法,只能这样写 ...

  8. jexus5.8.2 linux x64专业版 配置https

    一.环境 1.jexus版本:Jexus/5.8.2.8 Linux专业版 内置mono版本:Mono/4.6.2.7 2.操作系统:centOs7 jexus独立版由于是免安装版并且内置mono,所 ...

  9. 从零开始,DIY一个jQuery(1)

    从本篇开始会陪大家一起从零开始走一遍 jQuery 的奇妙旅途,在整个系列的实践中,我们会把 jQuery 的主要功能模块都了解和实现一遍. 这会是一段很长的历程,但也会很有意思 —— 作为前端领域的 ...

  10. 自定义Angular插件 - 网站用户引导

    最近由于项目进行了较大的改版,为了让用户能够适应这次新的改版,因此在系统中引入了“用户引导”功能,对于初次进入系统的用户一些简单的使用培训training.对于大多数网站来说,这是一个很常见的功能.所 ...