zoukankan      html  css  js  c++  java
  • ASP.Net中Ado.Net Entity Framework实际项目应用释疑

    image84

    关于Ado.Net Entity Framework 的理论、入门教学文章已不少了,但是很少有人讲到在ASP.Net项目中实际项目应用的问题,往往学的时候轻松搞定,一上手项目就一头雾水。

    比如在教程中最常见的这种形式的使用方法:

    using(MyObjectContext c=new MyObjectContext())

    {

    ……

    }

    如果在实际应用中,每每需要连接数据库,就造这么一个代码块的话,那么一个页面访问时就可能会创建数个数据库连接,致使并发用户访问数大打折扣;

    而假如只使用一个这样的代码块的话,那么由于分层、服务器控件、用户控件等因素,又难以将所有数据库访问操作都揉到这一个代码块当中;

    那么到底该怎样做才是最佳方案呢?

    这个问题或许是Entity Framework的使用者产生疑惑最多的一点。

    我在此将结合自己的经验,解答包括上述问题在内的一些在ASP.Net实际项目中容易产生的疑问。

    准备工作

    首先,我们需要搭建一个演示环境。

    建立一个数据库,并创建如下两个表:

    image3

    关系:Article的PostUser字段对应到User的ID字段

    将两个表分别填充一些数据:

    image9

    image6

    生成Entity Framwork模型:

     image48

    准备工作完成。

    如何设计业务逻辑层?

    如果要扩展实体类的功能,应该通过“部分类”(partial)实现:

    image17

    如果需要借助ObjectContext对象查询或更新数据库,应将ObjectContext定义为方法参数,而不是在业务逻辑层中创建ObjectContext对象。

    例如,下面的方法不应该出现在业务逻辑层:

     image33

    更好的做法是:

     image37

    上图中高亮的重载方法只应在需要时才编写,通常都可予以忽略。

    (方法中的统计总数的代码语句完全可以由LinQ语句替代完成,并且非常精简,而这里只是象征性演示,别太在意)

    如何快速通过主键获取对应实体?

    image41

    这样是从缓存中直接取出实体对象,效率非常高。

    如何优化查询性能?

    可通过CompiledQuery.Compile()预编译查询:

    image45

    如何在同一页面中共享一个ObjectContext?

    一般来说,一个页面只需要一个数据库连接,这样可以减少数据库的并发压力,使同一时间可以有更多用户访问网站。

    而通常情况下,我们都使用ObjectContext的无参构造函数创建包含默认连接的ObjectContext对象,因此,在同一页面中共享一个ObjectContext就能实现同一页面共享一个数据库连接的目标。

    接下来我们将在页面中放置两个EntityDataSource控件,分别获取所有用户及所有文章,并以ListView控件显示出来。

    同时还要放置一个用户控件,用来获取并显示每个用户曾发布的文章。

    我们先来创建用户控件界面:

    image52

    用户控件界面中仅包含一个ListView控件。

    (为了简单起见,ul中的li代码将由后台生成,然后直接绑定到这里)

    接着是后台代码:

     image60

    注意,这里定义了一个ObjectContext属性,程序将通过该属性访问数据库及业务逻辑层,但该属性并未在这里初始化,而是要由使用此用户控件的页面初始化该属性。

    接下来编写页面前台代码:

    image64

    简单的放置并配置了两个EntityDataSource及ListView,并放置了一个前面创建的用户控件。

    后台代码:

    image68

    这里也同样设置了一个ObjectContext属性,并在蓝色高亮处重写了OnInit,在其中进行初始化,并赋值给用户控件,然后在绿色高亮处重写了Dispose,对ObjectContext进行释放。

    这样用户控件就将和页面使用同一个ObjectContext对象了。

    然而,每个EntityDataSource还都会自己创建ObjectContext连接数据库,这显然不合我们的期望,解决办法是分别注册它们的ContextCreating、ContextDisposing事件,做如下处理:

    image72

    这样页面虽然多次在不同的位置访问数据库,但仅使用一个ObjectContext、一个数据库连接。

    执行结果:

    image90

    如何在多个ObjectContext共享一个数据库连接?

    EntityConnection即代表一个数据库连接,可以通过创建EntityConnection对象,并将其分配给多个ObjectContext对象,实现多ObjectContext共享单连接,具体方法可参看MSDN:http://msdn.microsoft.com/zh-cn/library/bb738582.aspx

    多ObjectContext共享一个连接,与整页面共享一个ObjectContext有什么不同呢?

    一般来说感觉不到什么不同,但当你将更改提交到数据库时,单个ObjectContext将维护全部相关事务,一旦提交失败将全部回滚,而多个ObjectContext就可以分别处理各自的事务,相比之下更具灵活性。

    结语

    在这里我仅以自己的经验总结而出了一些问题和解决方案,若有其他疑问欢迎补充,共同探讨。

    针对上面的问题,如有更好的解决方案的话,也欢迎赐教。

    下载范例源代码:

    下载本文的XPS版本:

  • 相关阅读:
    linux-cp
    linux-rmdir
    linux-tail
    linux-head
    linux 重定向
    hadoop环境安装及错误总结
    vim 图册
    为什么可以这么快! awk 与python的应用
    八大排序算法的 Python 实现
    linux的文件隐藏属性 chattr lsattr
  • 原文地址:https://www.cnblogs.com/SkyD/p/1526767.html
Copyright © 2011-2022 走看看