在存储模型中定义一个自定义函数
问题
您想在模型中定义一个自定义函数,而不是数据库中的存储过程。
解决方案
让我们说,你有一个数据库,保持轨道的成员Member和他们所发送的消息Message
这可能是因为,作为一个入门级程序员,你没有被授予数据库创建存储过程的访问权限。然而,作为明智的和富有成效的,你要来封装查询逻辑用于查找与信息最多的成员进入存储模式过程中的可重复使用的自定义函数。
要在存储模型中定义自定义函数,做以下步骤:
1、右键单击.edmx文件,并选择与➤XML(文本)编辑。这将打开的XML编辑器的edmx文件。
2、添加下列代码到<Schema>元素。这定义了自定义函数。
<Function Name="MembersWithTheMostMessages" IsComposable="false"> <CommandText> select m.* from Member m join ( select msg.MemberId, count(msg.MessageId) as MessageCount from Message msg where DateSend = @datesend group by msg.MemberId ) temp on m.MemberId = temp.MemberId order by temp.MessageCount desc </CommandText> <Parameter Name="datesend" Type="datetime" /> </Function>
3、打开设计界面的edmx文件。右键单击设计图面上,并选择“添加➤函数导入“。在对话框中,选择存储过程名称下拉MembersWithTheMostMessages。在导入的函数的名称”文本框中输入会员TheMostMessages。最后,选择实体作为返回类型,并选择成员作为实体类型。单击“确定”。
4、使用自定义函数,如下所示:
DateTime today = DateTime.Parse("5/7/2013"); using (var context = new School5Entities()) { var mem1 = new Member { Name = "Jill Robertson" }; var mem2 = new Member { Name = "Steven Rhodes" }; mem1.Messages.Add(new Message { DateSend = today, MessageBody = "Hello Jim", Subject = "Hello" }); mem1.Messages.Add(new Message { DateSend = today, MessageBody = "Wonderful weather!", Subject = "Weather" }); mem1.Messages.Add(new Message { DateSend = today, MessageBody = "Meet me for lunch", Subject = "Lunch plans" }); mem2.Messages.Add(new Message { DateSend = today, MessageBody = "Going to class today?", Subject = "What's up?" }); context.Members.Add(mem1); context.Members.Add(mem2); context.SaveChanges(); } using (var context = new School5Entities()) { Console.WriteLine("Members by message count for {0}", today.ToShortDateString()); var members = context.TheMostMessages(today); foreach (var member in members) { Console.WriteLine("Member: {0}", member.Name); } }
自定义函数与模型定义函数(见第11章)不同,自定义函数定义在存储模型中。这使得自定义函数更像是数据库中的传统存储过程。就像存储模型中定义了一个查询不真正存在于数据库中的“虚拟”表,存储模型中的一个自定义函数就像一个“虚拟”存储过程。在实体框架社区中的一些是指自定义函数作为本机函数。微软文档使用术语“自定义函数”,所以我们将使用这个术语“自定义函数”。
自定义函数可以帮助在以下情况下:
•您没有权限创建您需要在数据库中的存储过程。
•您要单独管理代码和数据库的部署。使用一个或多个自定义函数,可以部署代码,而不需要为数据库部署新的存储过程。
•在数据库中的现有存储过程中有与您的实体不兼容的参数。使用自定义功能,您可以创建一个抽象层,删除,添加或更改存储过程参数和实体上的属性之间的类型。