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. 恋爱虽易,相处不易:当EntityFramework爱上AutoMapper

    剧情开始 为何相爱? 相处的问题? 女人的伟大? 剧情收尾? 有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易 ...

  2. Asp.Net MVC中使用StreamReader读取“Post body”之应用场景。

    场景:有三个市场(Global.China.USA),对前台传过来的数据有些验证需要细化到每个市场去完成. 所以就出现了基类(Global)和派生类(China.USA) 定义基类(Global)Pe ...

  3. 80 端口被占用 pid=4

    80端口被pid=4的系统进程给占用的解决方法: 一般开发的时候我们都会安装sqlserver ,也会把Sql server Reporting Services 安装上去.原因就是这个服务占用了80 ...

  4. JS实现页面进入、返回定位到具体位置

    最为一个刚入职不久的小白...慢慢磨练吧... JS实现页面返回定位到具体位置 其实浏览器也自带了返回的功能,也就是说,自带了返回定位的功能.正常的跳转,返回确实可以定位,但是有些特殊场景就不适用了. ...

  5. 不懂CSS的后端难道就不是好程序猿?

    由于H5在移动端的发展如日中天,现在大部分公司对高级前端需求也是到处挖墙角,前端薪资也随之水涨船高,那公司没有配备专用的前端怎么办呢? 作为老板眼中的“程序猿” 前端都不会是非常无能的表现,那作为后端 ...

  6. 2Sum

    用哈希表(unordered_map)使得时间复杂度从O(n*n)降到O(n),空间复杂度从O(1)增到O(n):一边找一边插入哈希表 注意 在C++11以前要使用unordered_map需要 #i ...

  7. 易用BPM时代,企业如何轻松驾驭H3?

    众所周知,BPM作为企业发展的推动力,能敏捷高效的融合业务流程和信息资源.通过综合考虑流程的成本.效率.质量等方面因素,用IT系统将调整后的流程固化下来,从而降低企业管理成本,提高内部运营效率,提升企 ...

  8. 如何手动安装MySql

    想安装当然要先有一个MySql的安装包 这里使用的是mysql-5.7.12-winx64 安装包百度云:http://pan.baidu.com/s/1kVAuXuv  密码:hr39 1.要将压缩 ...

  9. C#与C++的发展历程第四 - C#6的新时代

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  10. ABP源码分析二十一:Feature

    Feature是什么?Feature就是对function的分类方法,其与function的关系就比如Role和User的关系一样. ABP中Feature具有以下属性: 其中最重要的属性是name, ...