Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列
11-3. 为一个”模型定义”函数返回一个计算列
问题
想从”模型定义”函数里返回一个计算列
解决方案
假设我们有一个员工(Employee)实体,属性有: FirstName, LastName,和BirthDate, 如
Figure 11-3所示.

Figure 11-3. An Employee entity with a few typical properties
我们想要创建一个”模型定义”函数,让它返回FirstName 和LastName 合并后的full name
. 我们想要创建另一个”模型定义”函数,让它返回根据BirthDate 列计算出的age
按以下操作:
1. 右击解决方案中的.edmx 文件, 打开方式 ➤ XML 编辑器.
2. 把 Listing 11-5 里的代码插入到.edmx文件的概念模型节点的<Schema> 标签下.这样就在模型里定义好了函数.
Listing 11-5. Code for Model-Defined Functions
<Function Name="FullName" ReturnType="Edm.String">
<Parameter Name="emp" Type="EFRecipesModel1103.Employee" />
<DefiningExpression>
Trim(emp.FirstName) + " " + Trim(emp.LastName)
</DefiningExpression>
</Function>
<Function Name="Age" ReturnType="Edm.Int32">
<Parameter Name="emp" Type="EFRecipesModel1103.Employee" />
<DefiningExpression>
Year(CurrentDateTime()) - Year(emp.BirthDate)
</DefiningExpression>
</Function>
3. 插入和查询模型的代码,如Listing 11-6所示的代码:.
Listing 11-6. 用eSQL 和LINQ两种方式调用(“模型定义”函数)来查询模型
class Program
{
static void Main(string[] args)
{
RunExample();
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
static void RunExample()
{
using (var context = new EFRecipesEntities1103())
{
context.Database.ExecuteSqlCommand("delete from chapter11.employee");
context.Employees.Add(new Employee
{
FirstName = "Jill",
LastName = "Robins",
Birthdate = DateTime.Parse("3/2/1976")
});
context.Employees.Add(new Employee
{
FirstName = "Michael",
LastName = "Kirk",
Birthdate = DateTime.Parse("4/12/1985")
});
context.Employees.Add(new Employee
{
FirstName = "Karen",
LastName = "Stanford",
Birthdate = DateTime.Parse("7/6/1963")
});
context.SaveChanges();
}
using (var context = new EFRecipesEntities1103())
{
Console.WriteLine("Query using eSQL");
var esql = @"Select EFRecipesModel1103.FullName(e) as Name,
EFRecipesModel1103.Age(e) as Age from
EFRecipesEntities1103.Employees as e";
var objectContext = (context as IObjectContextAdapter).ObjectContext;
var emps = objectContext.CreateQuery<DbDataRecord>(esql);
foreach (var emp in emps)
{
Console.WriteLine("Employee: {0}, Age: {1}", emp["Name"],emp["Age"]);
}
}
using (var context = new EFRecipesEntities1103())
{
Console.WriteLine("\nQuery using LINQ");
var emps = from e in context.Employees
select new
{
Name = MyFunctions.FullName(e),
Age = MyFunctions.Age(e)
};
foreach (var emp in emps)
{
Console.WriteLine("Employee: {0}, Age: {1}", emp.Name, emp.Age.ToString());
}
}
}
}
public class MyFunctions
{
[EdmFunction("EFRecipesModel1103", "FullName")]
public static string FullName(Employee employee)
{
throw new NotSupportedException("Direct calls are not supported.");
}
[EdmFunction("EFRecipesModel1103", "Age")]
public static int Age(Employee employee)
{
throw new NotSupportedException("Direct calls are not supported.");
}
}
上述Listing 11-6执行结果如下:
Query using eSQL
Employee: Jill Robins, Age: 37
Employee: Michael Kirk, Age: 28
Employee: Karen Stanford, Age: 50
Query using LINQ
Employee: Jill Robins, Age: 37
Employee: Michael Kirk, Age: 28
Employee: Karen Stanford, Age: 50
它是如何工作的?
我们的”模型定义”函数FullName()返回的是Edm.String类型, Age()返回的是Edm.Int32.这些函数定义在概念层,所以它们不直接引用实体数据模型系统以外的类型. 这些原始的类型容易转化为运行时系统的类型.
在 <DefiningExpression> 里或”模型定义”函数的函数体里,我们直接访问参数接收到的实体的属性.这里没必要用select 语句. 然后,结果表达式必须要有一个类型来匹配函数返回的类型.
在插入一些employee到我们的模型之后,我们的第一个查询用 eSQL. 我们构造一个eSQL 表达式来调用我们的两个”模型定义”函数,并且把结果投射到 Name 和Age列 . 我们的 eSQL 表达式的结果为一个包含Name和Age成员的匿名类型的集合.因为我们不是返回一个在模型里定义好的类型, 所以我们CreateQuery<T>()中的类型声明为DbDataRecord.然后我们遍历查询结果集,并把所有employee的name和age打印出来
在 LINQ 查询里, 我们从Employee实体集中检索,正如本章前面章节一样, .因为我们返回的也是一个标量值,所以我们需要定义一个相应的运行时方法.这些方法只是利用它的签名而不会被调用.
我们可以在Employee实体中为计算所得的full name 和age分别声明只读的属性,然而这样会使得这些计算在实体被取回时都要进行,但我们用”模型定义”函数,只有在我们需要用到这些属性时才进行计算
Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(11-1)译 -> 从“模型定义”函数返回一个标量值
第11章函数 函数提供了一个有力代码复用机制, 并且让你的代码保持简洁和易懂. 它们同样也是EF运行时能利用的数据库层代码.函数有几类: Rowset Functions, 聚合函数, Ranking ...
- 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(目录索引)
Chapter01. Getting Started with Entity Framework / 实体框架入门 1-1. A Brief Tour of the Entity Framework ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- 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-4)译 -> 有效地创建一个搜索查询
问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...
随机推荐
- Java多线程基础学习(一)
1. 创建线程 1.1 通过构造函数:public Thread(Runnable target, String name){} 或:public Thread(Runnable target ...
- 阿里云直播 C# SDK 如何使用
阿里云直播SDK的坑 1.直播云没有单独的SDK,直播部分被封装在CDN的相关SDK当中. 2.针对SDK,没有相关Demo. 3.针对SDK,没有相关的文档说明. 4.针对SDK的说明,官网上的说明 ...
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...
- 讓TQ2440也用上設備樹(1)
作者:彭東林 郵箱:pengdonglin137@163.com QQ:405728433 開發板 TQ2440 + 64MB 內存 + 256MB Nand 軟件 Linux: Linux-4.9 ...
- springMVC学习笔记--知识点总结1
以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...
- 破解SQLServer for Linux预览版的3.5GB内存限制 (UBUNTU篇)
在上一篇中我提到了如何破解RHEL上SQLServer的内存大小限制,但是Ubuntu上还有一道检查 这篇我将会讲解如何在3.5GB以下内存的Ubuntu中安装和运行SQLServer for Lin ...
- QT内省机制、自定义Model、数据库
本文将介绍自定义Model过程中数据库数据源的获取方法,我使用过以下三种方式获取数据库数据源: 创建 存储对应数据库所有字段的 结构体,将结构体置于容器中返回,然后根据索引值(QModelIndex) ...
- WEB安全隐患
org.apache.commons.lang.StringEscapeUtils 进行输入框内容处理 [StringEscapeUtils.escapeSql(str);StringEscapeUt ...
- Android中的flexboxlayout布局
提到FlexboxLayout大家估计有点模糊,它是谷歌最近开源的一个android排版库,它的前身Flexbox是2009年W3C提出了一种新的布局,可以简便.完整.响应式的实现页面布局,Flexb ...
- Android中Fragment的两种创建方式
fragment是Activity中用户界面的一个行为或者是一部分.你可以在一个单独的Activity上把多个Fragment组合成为一个多区域的UI,并且可以在多个Activity中再使用.你可以认 ...