zoukankan      html  css  js  c++  java
  • 利用 Linq to SQL 的数据访问层开发方式讨论

    为了较好的开发体验,在开发阶段,我喜欢用 Model -> DB 的次序来进行。
    也就是说,先在程序中创建一个 Linq to SQL Data Classes 类,在设计视图上设计好类图。然后,程序中执行一下如下的代码来生成数据库:

    if (db.DatabaseExists())
        db.DeleteDatabase();
    db.CreateDatabase();

    这样做的好处是让我们可以以面向对象的方式去设计程序,而不必过早的纠缠于数据库的细节中去。

    如果反过来,DB -> Model:

    先在 SQL Server 2005 中设计好表,手工设置外键等细节,然后将这些表拖放到设计界面上去生成类。


    这样的步骤,外键设置很容易出错,而且不容易设计继承关系。
    像单表继承这样的工作,最终还是要在 dbml 的设计视图中去设置的。

    还有一个坏处,就是生成的 Association,默认是双向关联的。但很多有时候我们需要的只是单向的关联,这也要到设计界面中去自己删除。
    比如一个人可以有几个通讯地址:
    生成 staff.Addresses 是有意义的,
    而反过来 address.Staffs 就意义不大。

    这样做有一个不好,就是每次调整设计(dbml)后,要重新生成数据库就会冲掉之前的测试数据。
    为了这个目的,我们可以学习 Rails 中的思路,创建一个测试固件(Test Fixtures)项目.可以做成 Console Application, 加到解决方案中。
    每次调整设计后,执行一遍即可。

    在看了 Kigg Starter Kit 代码之后,我发现可以参考它的思路。我们可以定义一个 IDataService 接口,其中定义各种数据操作。
    然后,再创建一个 DataContext 的 partial class. 让它继承这个接口,在其中包装一些相应的 linq to sql 操作,这样,UI 层的代码就可以做到很简单。

    为了做到不和 Linq to SQL 的具体实现解耦,以便在将来也许需要替换掉 Linq to SQL 的实现。我们在接口层始终使用 IDataService 来操作数据,其具体的 Linq to SQL 实现可以用依赖注入框架来配置,如 Unity Application Block 等。

    但这里我仍有疑问:实体如何传递呢?

    一种办法是自己再定义一个独立的 Model 层,然后我们把 IDataService 的操作中返回的每一个结果都以 Model 层里定义的实体来表示。虽然利用 .NET 3.5 里的语法写起来不算太麻烦,但因为 Linq to SQL 已经有了实体定义了,自己再创建一层势必造成非常多的重复。扩展性是好了,但维护起来不容易。

    另外,这样做也带来很多麻烦。比如在 Linq to SQL 里我们很多关联的实体集合可以设置为惰性加载。而返回自定义的实体集合后,就丧失了这个优势。否则,原来在 aspx 的界面里可以方便地: Eval("OrderDetails[0].UnitPrice") 获取关联信息,现在难道都要一次性加载出来吗?

    从这个角度来看,使用 Linq to SQL 后,开发方便了,但是要做到清晰的分层,不太容易。
    也许有人会说 ADO.NET Entity Framework 能做到这一点,但因为该框架还未正式发布,我也没有研究,这里不讨论。

    所以,目前我的 Linq to SQL 开发方式是,创建 Data Context 的 partial class 来封装操作,以简化 UI 层的操作代码为指导原则。而需要传递实体集的地方,就仍然使用 Linq to SQL 产生的映射类。
    如果 UI 层需要用到一个自定义的视图,则定义一个表示该视图的数据类用来返回。

    大家有什么好的建议,欢迎讨论。




  • 相关阅读:
    CentOS单用户模式下修改ROOT密码和grub加密
    CentOS配置SSH单向无密码访问
    物流追踪
    SpringBoot整合Redis及Redis
    小程序毫秒级倒计时(适用于拼团秒杀功能)
    foreach中的collection
    ArrayList和LinkedList的区别
    JavaScript 基础
    自用 goodsdetail
    JAVA常用处理数据
  • 原文地址:https://www.cnblogs.com/RChen/p/1198079.html
Copyright © 2011-2022 走看看