提示42. 怎样使用Code-Only创建一个动态模型

背景:

当我们给出使用Code-Only的例子,总是由创建一个继承自ObjectContext的强类型的Context开始。这个类用于引导模型。

例如这个类(处于简化问题考虑省略了属性体):

1 public class MyContext : ObjectContext
2 {
3    public ObjectSet<Category> Categories { get; }
4    public ObjectSet<Product> Products { get; }
5 }

这告诉CodeOnly使用2个EntitySet,一个称作CategoriesCategory实体的集合与一个称作ProductsProduct实体的集合,来引导一个模型。

然后如果需要你将来可以通过操作ContextBuilder来改进这个模型。

问题:

但是如果你没有一个强类型的Context类呢?

如果你决定在运行时需要一个模型,但没有一个适合的强类型Context类可以使用。

在今天早些时候一个客户恰好问我这个问题。

解决方案:

最终你可以直接使用ObjectContext。当你通过Code-Only做这个工作时对模型一无所知。但是这不是那么糟糕,所有你需要做的就是明确的告诉Code-Only通常可以由强类型context了解到的所有信息。

例如这个:

1 public ObjectSet<Person> People { get; }

可以被转换为这个:

1 var builder = new ContextBuilder<ObjectContext>();
2 builder.RegisterSet<Person>(“People”);

有趣吗?

结尾的例子:

这个例子,演示完全不使用强类型ObjectContext下将一个Person对象(BillG)存储到数据库并再次检索出来:

首先是Person类(这是个POCO):

1 public class Person
2 {
3     public int ID { get; set; }
4     public string Firstname { get; set; }
5     public string Surname { get; set; }
6 }

接下来是建立ObjectContext的代码:

 1 // Create the contextbuilder, and tell it about the People set. 2 var builder = new ContextBuilder<ObjectContext>(); 3 builder.RegisterSet<Person>("People");4 // Create a connection 5 string connstr = @"Data Source=.\SQLEXPRESS;Initial Catalog=PeopleDb;Integrated Security=True;Pooling=False;MultipleActiveResultSets=True"; 6 var conn = new SqlConnection(connstr); 7 8 // Create an ObjectContext from the builder 9 using (ObjectContext ctx = builder.Create(conn))
10 {
11     // Create the database if it doesn’t already exist
12     if (!ctx.DatabaseExists())
13        ctx.CreateDatabase();
14
15     // Create Bill
16     Person p = new Person {
17         ID = 1,
18         Firstname = "Bill",
19         Surname = "Gates"
20     };
21
22     // Add Bill to the context
23     // UPDATE: thanks to danny for the simplification
24     ctx.CreateObjectSet<Person>().AddObject(p);
25  using the general purpose
26     // AddObject method.
27     // The only tricky part is the EntitySet name with must
28     // be qualified with the the container name,
29     // in this case is ObjectContext.
30     ctx.AddObject("ObjectContext.People", p);
31     ctx.SaveChanges();
32     // Issue a query against the People set.
33     var bill = (from person in ctx.CreateObjectSet<Person>()
34                 where person.Firstname == "Bill"
35                 select person).Single();
36     // Make and Save a change.
37     bill.Firstname = "William";
38     ctx.SaveChanges();
39 }

就不是强类型的而论这非常简单了。

提示43. 怎样通过一个Data Service的验证

问题:

当我们编写访问一个Data Service的代码,如SharePoint,客户端程序必须提供一系列有效的凭据,否则你将收到一个”401 Unauthorized”的响应。

针对与DataServie宿主在同一网站上的Silverlight应用,通常会自动处理好这个问题。

但对于如WPF应用,这需要手动处理。

解决方案:

这个解决方案在你执行任何查询或更新之前在DataServieContext上设置凭证属性,像这样:

1 Uri uri = new Uri("http://mflasko-dev/_vti_bin/listdata.svc"));
2 TeamSiteDataContext ctx = new TeamSiteDataContext(uri);
3 ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;
4 …

就是这样。

当然如果需要你可以提供另一套凭证信息,但是一般来说,DefaultCredentials就是你想要的。

提示44. 怎样导航到一个Odata兼容服务

最近我做了一个关于Data Service与Odata的速成课程。

在这个过程中我发现我的笔记可能对大家有用。

这里给出我的备忘单供你快速掌握Odata Url。

注意:Odata服务可能未必完全支持下面这些特性:但是如果它们支持,这就是你使用它们的方法。

服务:

所有服务由一个宿主于某一地方的Data Service开始:

http://server/service.svc

基本查询:

通过资源集(resource set)来访问Data Service实体,像这样:

http://server/service.svc/People

使用主键来请求一个指定的实体,像这样:

http://server/service.svc/People(16)

或通过使用一个到你知道的对象的关联引用:

http://server/service.svc/People(16)/Mother

这请求16号人的母亲。

一旦你可以识别出一个实体,你可以直接导航到它的属性:

http://server/service.svc/People(16)/Mother/Firstname

$value:

但是上一个查询将属性值包在XML中,如果你仅想要单纯的属性值,可以像这样在url后面附加一个$value:

http://server/service.svc/People(16)/Mother/Firstname/$value

$filter:

你可以使用$filter来过滤资源集:

http://server/service.svc/People?$filter=Firstname  eq ‘Fred’

注意过滤条件字符串中使用单引号。

而数字不需要引号:

http://server/service.svc/Posts?$filter=AuthorId eq 1

要按时间过滤你需要在过滤条件中标识出时间,如下:

http://server/service.svc/Posts?$filter=CreatedDate eq DateTime'2009-10-31'

也可以通过关联引用来过滤:

http://server/service.svc/People?$filter=Mother/Firstname eq 'Wendy'

你可以在过滤条件中使用的基本运算符:

Operator

Description

C# equivalent

eq

equals

==

ne

not equal

!=

gt

greater than

>

ge

greater than or equal

>=

lt

less than

<

le

less than or equal

<=

and

and

&&

or

or

||

()

grouping

()

如果需要还有一系列可以在过滤条件中使用的函数。

$expand:

如果你想在结果中包含相关项目,像这样使用$expand:

http://server/service.svc/Blogs?$expand=Posts

这将返回匹配的Blogs及每个Blog的post。

$select:

一些Data Service允许你将结果限制在仅你需要的属性 – 又称投影 – 例如如果你仅想要匹配Post的Id与Title,你需要如下这样的Url:

http://server/service.svc/Posts?$select=Id,Title

你甚至也可以映射到关联对象的属性,如这样:

http://server/service.svc/Posts?$expand=Blog&$select=Id,Title,Blog/Name

这仅映射到了每个Post的 Id,Title与Blog的名称。

$count:

如果你仅想知道将返回多少条记录,而不检索它们,你需要使用$count:

http://server/service.svc/Blogs/$count

注意$count成为URL的片段之一-它不是查询字符串的一部分-所以如果你想与另一个操作如$filter合并,你需要将$count放在前面,像这样:

http://server/service.svc/Posts/$count?$filter=AuthorId eq 6

这个查询返回作者是6号person的帖子的数量。

$orderby:

如果你需要结果是排序过的,可以使用$orderby:

http://server/service.svc/Blogs?$orderby=Name

返回的结果是升序排序,要进行降序排序你需要:

http://server/service.svc/Blogs?$orderby=Name%20desc

要首先按一个属性排序,然后按另一个属性排序,你需要:

http://server/service.svc/People?$orderby=Surname,Firstname

如果需要也可以在其中加入desc。

$top:

如果你仅想要前10条项目,可以像这样使用$top:

http://server/service.svc/People?$top=10

$skip

如果你仅对某一页数的数据感兴趣,你需要联合使用$top与$skip:

这告诉Data Service跳过前20条匹配结果并返回下10条数据。当每页有10个项而你需要显示第3页结果时这很有用。

注意:通常将$top&$skip与$orderby合并使用是一个好主意,以保证由底层数据源检索到的结果的顺序是一致的。

$inlinecount&$skiptoken:

使用$top与$skip允许客户端控制分页。

但是服务器也需要一种方法来控制分页-以最小化服务初级用户及那些恶意用户所需的负载-OData协议通过Server Driven Paging(服务器驱动的分页)来完成这个任务。

当Server Driven Paging开启后,即使客户端请求所有记录,但它们将只会得到一个页的结果。

正如你想象,这会给客户端应用开发人员带来一点麻烦。

如果客户端需要知道到底有多少结果,它们可以在查询后追加$inlinecount选项,如下:

http://server/service.svc/People?$inlinecount=allpages

结果将会“内联”包含一个总数,及一个服务器生成的用于获取下一页结果的url。

这个服务器生成的url包含一个$skiptoken,这与一个游标或书签等效,以通知服务器由哪重新开始:

http://server/service.svc/People?$skiptoken=4

$links

有时候你只需得到与实体关联的一个特殊实体的url,这时候就用到$links了:

http://server/service.svc/Blogs(1)/$links/Posts

这告诉Data Service返回Blog1相关的所有Posts的链接-即url。

$metadata

如果你需要知道一个Odata兼容的数据服务暴露的模型的信息,你可以通过在服务的根路径后面拼接一个$metadata选项,如下:

http://server/service.svc/$metadata

这将返回一个Data Service暴露的包含概念模型(又称EDM)的EDXM文件。

总结

这会帮助你早日上手。

我将更多的探索Data Service与Odata,我也将与你分享我的所学,请锁定我的博客。

提示45. 怎样在运行时置换EF元数据

背景:

默认情况下Entity Framework将它的元数据作为一个资源嵌入程序集中。

同时它也将一个引用了这些资源连接字符串放入App或Web配置文件中,像这样:

1 <add name="BloggingEntities" connectionString="metadata=res://*/Blogging.csdl|res://*/Blogging.ssdl|res://*/Blogging.msl;provider=System.Data.SqlClient;
2 provider connection string=&quot;Data Source=.\SQLEXPRESS;Initial Catalog=TipsDatabase;Integrated Security=True;MultipleActiveResultSets=True&quot;"
3 providerName="System.Data.EntityClient" />

这使其可以很容易的开始:

1 using (BloggingEntities ctx = new BloggingEntities())
2 {

注意:使用res://*告诉EF在程序集资源内部查找各种各样的元数据。

问题

但是将元数据嵌入作为资源同时意味着它本质上是不可改变的。

假如你需要在运行时更改它怎么办呢?

有很多原因是你想要在运行时更改元数据,但是也许最可能的原因是在生产环境你不得不配合有一套不同数据库设计想法的DBA。

一般情况下这意味着你不得不由于数据库的更改来更改一部分存储模型(SSDL)与映射(MSL)。

这样做完全可以,事实上这是使用Entity Framework的一大好处,只要概念模型或者称CSDL—开发的程序所依赖的东西—保持不变。

解决方案

所以怎样在运行时插入一个不同的MSL与SSDL呢?

下面是相关的步骤:

步骤1:

得到’元数据项目’:

1. 在设计器画布上右击,点击属性:

2. 将’元数据项目处理’设置为’ 复制到输出目录’:

3. 生成项目,查看bin\debug(或bin\release)目录:

步骤2:

现在你有了文件形式的CSDL/MSL/SSDL,很容易替换其中一个或多个(一般是SSDL与MSL)为与你环境匹配的版本。所以你可以有两套,其一用于开发环境,另一套用于生成环境。

然后你需要做的仅是修改你的连接字符串来指向正确的文件集,类似下面这样:

 1 var connStr = 2 @"metadata=.\Blogging.csdl|.\Production.ssdl|.\Production.msl; 3     provider=System.Data.SqlClient; 4     provider connection string="" 5            Data Source=.\SQLEXPRESS; 6            Initial Catalog=TipsDatabase; 7            Integrated Security=True; 8            MultipleActiveResultSets=True 9    """;
10
11 using (BloggingEntities ctx = new BloggingEntities(connStr))
12 {

注意现在使用的连接字符串不是res://而是.\,这告知EF在与应用程序相同的目录下查找元数据。

事情就是这样。

转载于:https://www.cnblogs.com/sylone/p/6094578.html

Entity Framework技巧系列之十一 - Tip 42 - 45相关推荐

  1. Entity Framework技巧系列之二 - Tip 6 - 8

    提示6. 如何及何时使用贪婪加载 什么时候你需要使用贪婪加载? 通常在你的程序中你知道对查询到的实体将要进行怎样的操作. 例如,如果你查询一个订单以便为一个客户重新打印,你知道没有组成订单的项目即产品 ...

  2. (翻译)Entity Framework技巧系列之一 - Tip 1 - 5

    本系列英文原文出自. 提示1. 在Entity Framework中怎样排序关系(Relationships) 问题: 在Entity Framework论坛中常会看到关于排序相关联项目的问题. 例如 ...

  3. Entity Framework 实践系列 —— 搞好关系 - 单相思(单向一对一,one-to-one)

    原以为躲入代码世界,就可以不用搞关系,哪知"关系无处不在".写代码多年之后,终于明白"面向对象的关键是搞好对象之间的关系".而Entity Framework作 ...

  4. Entity Framework技术系列之2:三种开发模式实现数据访问

    前言 Entity Framework支持Database First.Model First和Code Only三种开发模式,各模式的开发流程大相径庭,开发体验完全不一样.三种开发模式各有优缺点,对 ...

  5. Entity Framework技术系列之1:数据访问技术概述

    前言 .NET Framework自2002年发布以来,已经历了十来个年头.相应的,.NET平台上的数据访问技术也在不断发展,从最基础的ADO.NET,到SqlHelper简单帮助类,到DAAB(Da ...

  6. 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)

    前言 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这是一个对Entity Framework进行扩展 ...

  7. Entity Framework Core系列教程-25-Entity Framework Core日志

    Entity Framework Core日志 我们经常需要在EF Core中记录SQL并更改跟踪信息以进行调试. EF Core日志记录自动与.NET Core的日志记录机制集成.因此,在隐含使用E ...

  8. Entity Framework Core系列教程-23-原生SQL查询

    在Entity Framework Core中执行原生SQL查询 Entity Framework Core提供了DbSet.FromSql()方法来对基础数据库执行原始SQL查询,并将结果作为实体对 ...

  9. Entity Framework Core系列教程-3为现有数据库生成实体模型

    在Entity Framework Core中为现有数据库创建模型 在这里,您将学习如何在Entity Framework Core中为现有数据库创建上下文和实体类.为现有数据库创建实体和上下文类称为 ...

最新文章

  1. 零拷贝 zero-copy 原理
  2. <X86汇编语言:实模式到保护模式>四十六 中断和异常的处理与抢占式多任务
  3. javascript基础 (2)
  4. noj Nightmare
  5. html元素嵌套与并列,HTML的元素嵌套规则
  6. Azure Site Recovery之启用复制
  7. 去除listView和recyclerview滑动到顶部和底部边界的阴影
  8. Linux下 mysql5.7的彻底卸载
  9. To程序员:要写出好代码,你需要懂点儿“底层思维”
  10. POJ2492A Bug's Life【并查集+根节点偏移】
  11. Springboot
  12. 实地测试电源模块性能
  13. 收费最低的云存储_营业收费系统|自来水管理系统|自来水公司收费管理系统|手机移动抄表|网上营业厅|短信服务平台...
  14. 增加项目报告功能,支持与TAPD、Jira、禅道双向同步缺陷,MeterSphere开源持续测试平台v1.15.0发布
  15. react hook 造轮子
  16. js设置元素垂直居中
  17. 【讲解 + 模板】Dijkstra迪杰斯特拉+堆优化
  18. 7-40 奥运排行榜(25 分)
  19. 皇甫懒懒 华清远见Java学习笔记-身份证校验
  20. 《数字连线大招版》攻略

热门文章

  1. python安装步骤图解-Python安装与卸载流程详细步骤(图解)
  2. python利器怎么编程-python 开发利器UliPad(图文详细介绍)
  3. python处理excel-python处理excel总结
  4. python开发工程师面试题-超实用面试必看,Python工程师面试题
  5. python爬虫正则表达式实例-Python爬虫(十一)_案例:使用正则表达式的爬虫
  6. python操作excel-Python对Excel(*.xls)的操作
  7. python画直方图代码-python plotly画柱状图代码实例
  8. 零基础python必背代码-30个Python常用极简代码,拿走就用
  9. python有什么作用-大数据学习之python语言有什么作用?
  10. python散点图拟合曲线-使用python通过点拟合曲线