Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型
11-6.从一个”模型定义”函数里返回一个复杂类型
问题
想要从一个”模型定义”函数返回一个复杂类型
解决方案
假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 11-6所示 .

Figure 11-6. A model for patient visits
我们想要创建一个”模型定义”函数,返回一个概要信息,包括:病人名字,病人的访客数,和病人累积的账单. 此外,我们只过滤出年龄超过40岁的病人:
1. 在模型设计视图上,右击, 新建 ➤ 复杂类型.
2.在模型浏览器里右击新建的复杂类型,重命名为VisitSummary, 然后给复杂属性添加下列属性::
a. Name: String,不可为null
b. TotalVisits: Int32, 不可为null
c. TotalCost:Decimal, 不可为null
3. 在解决方案资源管理器中右击.edmx 文件, 打开方式 ➤ XML 编辑器.
4. 在.edmx 文件的概念模型conceptual models)的<Schema> 标签下插入Listing 11-11所示的代码,这样函数主定义好了.
Listing 11-11. The GetVisitSummary() Model-Defined Function
<Function Name="GetVisitSummary" ReturnType="Collection(EFRecipesModel.VisitSummary)">
<DefiningExpression>
select VALUE EFRecipesModel.VisitSummary(pv.Patient.Name,
Count(pv.VisitId),Sum(pv.Cost))
from EFRecipesEntities.PatientVisits as pv
group by pv.Patient.Name
</DefiningExpression>
</Function>
5. 用如 Listing 11-12.所示的代码来插入和查询这个模型:
Listing 11-12. Using eSQL and LINQ with the VisitSummary() Function to Query the Model
class Program
{
static void Main(string[] args)
{
RunExample();
}
static void RunExample()
{
using (var context = new EFRecipesEntities())
{
string hospital = "Oakland General";
var p1 = new Patient { Name = "Robin Rosen", Age = 41 };
var p2 = new Patient { Name = "Alex Jones", Age = 39 };
var p3 = new Patient { Name = "Susan Kirby", Age = 54 };
var v1 = new PatientVisit
{
Cost = 98.38M,
Hospital = hospital,
Patient = p1
};
var v2 = new PatientVisit
{
Cost = 1122.98M,
Hospital = hospital,
Patient = p1
};
var v3 = new PatientVisit
{
Cost = 2292.72M,
Hospital = hospital,
Patient = p2
};
var v4 = new PatientVisit
{
Cost = 1145.73M,
Hospital = hospital,
Patient = p3
};
var v5 = new PatientVisit
{
Cost = 2891.07M,
Hospital = hospital,
Patient = p3
};
context.Patients.Add(p1);
context.Patients.Add(p2);
context.Patients.Add(p3);
context.SaveChanges();
}
using (var context = new EFRecipesEntities())
{
Console.WriteLine("Query using eSQL...");
var esql = @"Select value ps from EFRecipesEntities.Patients
as p join EFRecipesModel.GetVisitSummary()
as ps on p.Name = ps.Name where p.Age > 40";
var objectContext = (context as IObjectContextAdapter).ObjectContext;
var patients = objectContext.CreateQuery<VisitSummary>(esql);
foreach (var patient in patients)
{
Console.WriteLine("{0}, Visits: {1}, Total Bill: {2}",
patient.Name, patient.TotalVisits.ToString(),
patient.TotalCost.ToString("C"));
}
}
using (var context = new EFRecipesEntities())
{
Console.WriteLine();
Console.WriteLine("Query using LINQ...");
//译注:遇到了与11-5一样的异常
var patients = from p in context.Patients
join ps in context.GetVisitSummary() on p.Name equals
ps.Name
where p.Age >= 40
select ps;
foreach (var patient in patients)
{
Console.WriteLine("{0}, Visits: {1}, Total Bill: {2}",
patient.Name, patient.TotalVisits.ToString(),
patient.TotalCost.ToString("C"));
}
}
}
}
partial class EFRecipesEntities
{
[EdmFunction("EFRecipesModel", "GetVisitSummary")]
public IQueryable<VisitSummary> GetVisitSummary()
{
var objectContext = (this as IObjectContextAdapter).ObjectContext;
return objectContext.CreateQuery<VisitSummary>(
Expression.Call(Expression.Constant(this),
(MethodInfo)MethodInfo.GetCurrentMethod()).ToString());
}
}
Listing 11-12代码输出结果如下:
Query using eSQL...
Robin Rosen, Visits: 2, Total Bill: $1,221.36
Susan Kirby, Visits: 2, Total Bill: $4,036.80
Query using LINQ...
Robin Rosen, Visits: 2, Total Bill: $1,221.36
Susan Kirby, Visits: 2, Total Bill: $4,036.80
它是如何工作的?
我们先在模型里添加一个复杂类型,接着创建如Listing 11-11的GetVisitSummary() 函数,它能返回包含这个新建的复杂类型的集合.注意:复杂类型的构造函数接受参数的顺序要与我们定义它的属性时的顺序一致. 你可能需要检查.edmx文件,确保设计器按我们添加的顺序是一致.
由于我们函数返回IQueryable<VisitSummary>, 所以我们需要实现引导代码. 同样,因为我们需要访问ObjectContext的QueryProvider,所以我们需要在EFRecipesEntities类中实现运行时方法.
如果我们把这个函数用在LINQ查询中,你可能需要让这个方法返回IQueryable<DbDataRecord>给匿名类型.虽然我们的这个集合不能进一步过滤,但是包含复杂类型的集合是可以被进一点过滤的.
Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列
11-3. 为一个”模型定义”函数返回一个计算列 问题 想从”模型定义”函数里返回一个计算列 解决方案 假设我们有一个员工(Employee)实体,属性有: FirstName, LastName,和 ...
- 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(9-7)译->在WCF服务中序列化代理
9-7. 在WCF服务中序列化代理 问题 从一个查询里返回一个动态代理对象,想要把它序列为一个POCO(Plain-Old CLR Objects)对象. 实现基于POCO实体对象, 在运行时,EF会 ...
- Entity Framework 6 Recipes 2nd Edition(12-8)译 -> 重新获取一个属性的原始值
12-8. 重新获取一个属性的原始值 问题 在实体保存到数据库之前,你想重新获取属性的原始值 解决方案 假设你有一个模型 (见 Figure 12-11) 表示一个员工( Employee),包含工资 ...
- 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 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
随机推荐
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 菜鸟学Struts2——Struts工作原理
在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...
- HashSet HashTable 与 TreeSet
HashSet<T>类 HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素. HashSet& ...
- 使用Zabbix监控Oracle数据库
Orabbix介绍 监控Oracle数据库我们需要安装第三方提供的Zabbix插件,我们先测试比较有名的Orabbix,http://www.smartmarmot.com/product/orabb ...
- .NET Core采用的全新配置系统[9]: 为什么针对XML的支持不够好?如何改进?
物理文件是我们最常用到的原始配置的载体,最佳的配置文件格式主要由三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
Insert是T-sql中常用语句,Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少.但我 ...
- 免费高效实用的.NET操作Excel组件NPOI(.NET组件介绍之六)
很多的软件项目几乎都包含着对文档的操作,前面已经介绍过两款操作文档的组件,现在介绍一款文档操作的组件NPOI. NPOI可以生成没有安装在您的服务器上的Microsoft Office套件的Excel ...
- ASP.Net MVC——使用 ITextSharp 完美解决HTML转PDF(中文也可以)
前言: 最近在做老师交代的一个在线写实验报告的小项目中,有这么个需求:把学生提交的实验报告(HTML形式)直接转成PDF,方便下载和打印. 以前都是直接用rdlc报表实现的,可这次牵扯到图片,并且更为 ...
- MyBatis源码分析(二)语句处理器
StatementHandler 语句处理器,主要负责语句的创建.参数的设置.语句的执行.不负责结果集的处理. Statement prepare(Connection connection, Int ...
- React Native 之 Text的使用
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...