我的WCF4 Rest Service及Entity Framework with POCO之旅(三)——用Entity Framework和POCO Template实现数据模型及存储

既然这个系列标题中都含有Entity Framework和POCO,这两者若到第三篇还不出现那就太奇怪了。本文将介绍如何使用Entity Framework和POCO来实现数据模型的创建以及数据存储。

接着上文,我们现在已经有了一个微博服务。但是,一旦网站重启或者IIS重启,我们就会丢失之前所有发布的微博,这样的服务显然不是我们所能接受的,我们接下来要构建服务的数据存储。使用Entity Framework的Model-First设计方式,可以大大简化这个过程。

使用Entity Data Model创建数据模型

我们首先创建一个类库项目WcfRestServiceDemo.Data,然后添加新项“ADO.NET Entity Data Model”:
image

选择数据源,如果有现成的数据源的话可以从数据库导入。我们选择Empty model, 新创建数据模型。
image

从工具箱中找到Entity,拖入设计器,参考之前创建的数据类型,修改得到:
image

到这里数据模型就创建完了。下面我们要把它同步到SQL Server。

由模型生成数据库

到目前为止,模型还只存在C#项目中,虽然我们已经可以写代码来操纵数据,但实际上是无法运行的(或者说一运行就会挂掉的)。

要将模型同步到SQL Server,对设计器视图点右键,选择Generate Database from Model…
image

选择一个连接,没有的话就创建一个:
image

然后对应的SQL脚本就自动生成好了:
image

打开WcfRestServiceDemo.edmx.sql,右键选择Execute SQL,成功后模型就同步到SQL Server了。
image

修改服务代码

现在数据模型和数据存储都做好了,我们要修改服务代码来使用新的数据模型。

删去Microblog.cs,添加对WcfRestServiceDemo.Data和System.Data.Entity的引用,并修改MicroblogService.cs代码如下:


要让Entity Framework正常工作,我们还需要把它生成的app.config文件中的ConnectionString复制到服务的web.config文件中:

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

这里附带一提,有的时候我们会遇到无法正确加载Model的情形,这时只要将上面那个连接字符串中的*替换成数据模型(*.edmx)所在的程序集名称(这里是WcfRestServiceDemo.Data),显式指定搜索路径即可。

好,都改好了,现在测试一下服务,我先手工往数据库中插入一条记录,然后访问
http://localhost:6421/microblogs/
image

怎么回事?Content, Id, PublishTime这些属性倒是一个也不少,但是也多了很多其他的东西。这是因为与POCO不同,基于EntityObject的Entity Data Model支持更改提醒、关系管理等许多其他功能,所以会包含更多的属性,只不过在我们这个应用场景中,并不需要这些支持。另一个问题是,这时默认的命名空间变成了
xmlns=http://schemas.datacontract.org/2004/07/WcfRestServiceDemo.Data
而且由于Microblog这个DataModel是自动生成的,我没有办法改它的DataContractAttribute(改了下次生成又会变回来):

1
2
3
4
5
6
7
[EdmEntityTypeAttribute(NamespaceName="WcfRestServiceDemo", Name="Microblog")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Microblog : EntityObject
{
    
}

要解决上述问题,我们该请出下一位主角POCO了。

使用ADO.NET C# POCO Entity Generator生成POCO模型

POCO全称Plain-Old CLR Objects(中文不知道怎么说)。以前有很多人手写POCO模型,不过现在已经有了一个非常强大的基于T4模板的模型生成器。

打开Visual Studio 2010的Extension Manager,找到ADO.NET C# POCO Entity Generator并安装(或者在这里下载):
image

然后打开WcfRestServiceDemo.edmx,右键选择Add Code Generation Item…:
image

找到刚才安装的模板:
image

创建结果:
image

Model.Context.tt和Model.tt分别是Container和Entity的T4模板。现在再运行一下服务,获取所有微博:
image

为什么会Empty Response? 调试一下服务,发现返回的类型不是Microblog, 而是System.Data.Entity.DynamicProxies.Microblog_
C60A574FC06ABEF4672858332CE687DDE70D188AD3BD73ED2731E8854D30C927,而WCF并不认识这个类型。这是因为默认的Entity Data Model启用了LazyLoading和Proxy机制的缘故。这两个特性我以后也许会详细讲,不过目前我们只要把它们关闭就好。虽然Model设计器提供了下面这个属性可以修改:
image

但是当我改成False然后对Model.Context.tt右键选择Run Custom Tool 重新生成Container代码,却没有任何效果,Container构造器代码依旧如下:
image

如果有哪位高手知道应该如何设置,请告诉我。我们现在先通过扩展Container类的方法来解决这个问题,下一篇讲如何通过修改T4模板来改变生成的Container。

在WcfRestServiceDemo.Data中创建WcfRestServiceDemoContainer.cs,代码如下:

这里我顺便写了几个帮助方法,因为每次使用Container时写using很麻烦,关键是我经常改完数据忘记调SaveChanges().

最后修改MicroblogService.cs代码如下:

再次访问http://localhost:6421/microblogs/

image

啊哈,又回到最初干净的状态了。只是Namespace问题以及属性名称的大小写问题还是没有解决,但是我们已经离目标更近一步了,我将在下一章讨论这些。

小结

本文介绍了:

  • 如何用Entity Framework的Model-First方式构建数据模型及数据存储
  • 如何改用POCO实现数据模型
  • 如何关闭LazyLoading和ProxyCreation
  • 以及一点点代码的sugar

我的WCF4 REST Service及Entity Framework with POCO之旅系列

posted on   Gildor Wang  阅读(3010)  评论(11编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2010-03-31 如何破解Windows Phone 7模拟器以运行所有内置应用

导航

< 2011年3月 >
27 28 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 1 2
3 4 5 6 7 8 9

统计

点击右上角即可分享
微信分享提示