当前位置:  开发笔记 > 编程语言 > 正文

数据访问层到业务对象的最佳"模式"

如何解决《数据访问层到业务对象的最佳"模式"》经验,为你挑选了2个好方法。

我正试图找出最干净的方法来做到这一点.

目前我有一个客户对象:

public class Customer
{
    public int Id {get;set;}
    public string name {get;set;}
    public List emailCollection {get;set}
    public Customer(int id)
    {
        this.emailCollection = getEmails(id);
    }
}

然后我的Email对象也很基本.

public class Email
{
    private int index;
    public string emailAddress{get;set;}
    public int emailType{get;set;}
    public Email(...){...}
    public static List getEmails(int id)
    {
        return DataAccessLayer.getCustomerEmailsByID(id);
    }
}

DataAccessLayer当前连接到数据库,并使用SqlDataReader迭代结果集并创建新的Email对象,并将它们添加到完成时返回的List.

那么我在哪里以及如何改进呢?

我是否应该让我的DataAccessLayer返回一个DataTable并将其留给Email对象进行解析并将List返回给Customer?

我猜"工厂"可能是错误的单词,但是我应该有另一种类型的EmailFactory从DataAccessLayer获取DataTable并将List返回给Email对象吗?我想这种声音多余......

将我的Email.getEmails(id)作为静态方法,这是否是正确的做法?

我可能只是试图找到并应用最好的"模式"来完成一项简单的任务.

谢谢.


跟进

我创建了一个工作示例,其中我的域/业务对象通过现有数据库中的id提取客户记录.nhibernate中的xml映射文件非常简洁.在我按照教程设置会话和存储库工厂之后,拉动数据库记录非常简单.

但是,我注意到了巨大的性能损失.

我的原始方法由DB上的存储过程组成,该过程由DAL对象调用,该对象将结果集解析为我的域/业务对象.

我用30分钟的原始方法来获取单个客户记录.然后我用nhibernate方法计时3000ms来获取相同的记录.

我错过了什么吗?或者使用这种nhibernate路由会有很多开销吗?

否则我喜欢代码的清洁度:

protected void Page_Load(object sender, EventArgs e)
{
    ICustomerRepository repository = new CustomerRepository();
    Customer customer = repository.GetById(id);
}

public class CustomerRepository : ICustomerRepository
        {
            public Customer GetById(string Id)
            {
                using (ISession session = NHibernateHelper.OpenSession())
                {
                    Customer customer = session
                                        .CreateCriteria(typeof(Customer))
                                        .Add(Restrictions.Eq("ID", Id))
                                        .UniqueResult();
                    return customer;
                }
            }
        }

我接下来的例子让我创建了一个帮助类来帮助管理Session,也许这就是为什么我得到这个开销?

public class NHibernateHelper
    {
        private static ISessionFactory _sessionFactory;
        private static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    Configuration cfg = new Configuration();
                    cfg.Configure();
                    cfg.AddAssembly(typeof(Customer).Assembly);
                    _sessionFactory = cfg.BuildSessionFactory();
                }
                return _sessionFactory;
            }

        }

        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }
    }

随着我正在努力的应用程序,速度是至关重要的.最终,很多数据将在Web应用程序和数据库之间传递.如果需要一个代理1/3秒来提升客户记录而不是3秒,这将是一个巨大的打击.但是如果我做了一些奇怪的事情并且这是一次初始设置成本,那么如果性能与在DB上执行存储过程一样好,那么它可能是值得的.

仍然愿意接受建议!


更新.

我正在废弃我的ORM/NHibernate路线.我发现性能太慢,无法证明使用它.基本的客户查询对我们的环境来说需要太长时间.与亚秒响应相比,3秒钟太多了.

如果我们想要慢查询,我们只需保留当前的实现.重写它的想法是大幅增加时间.

然而,在过去一周玩过NHibernate之后,它是一个很棒的工具!它不太适合我对这个项目的需求.



1> James Orr..:

如果你现在的配置有效,为什么要搞乱呢?这听起来并不像是在识别代码的任何特定需求或问题.

我确信一堆OO类型可以挤在一起并在这里建议各种重构,以便正确的责任和角色得到尊重,甚至有人甚至可能试图以一两个设计模式进行设计.但是你现在拥有的代码很简单,听起来没有任何问题 - 我会说离开它.


一个建议是向业务对象添加更多"业务"行为.好像上面没有正确使用业务对象.

2> George Mauer..:

我实际上已经实现了一个DAL层,基本上是做NHibernate所做的但是手动完成.NHibernate所做的是创建一个继承自Domain对象的Proxy类(应将其所有字段标记为虚拟).所有数据访问代码都进入属性覆盖,实际上非常优雅.

我通过让我的存储库自己填写简单属性并仅使用代理进行延迟加载来简化这一点.我最终得到的是一组这样的类:

public class Product {
  public int Id {get; set;}
  public int CustomerId { get; set;}
  public virtual Customer Customer { get; set;}
}
public class ProductLazyLoadProxy {
  ICustomerRepository _customerRepository;
  public ProductLazyLoadProxy(ICustomerRepository customerRepository) {
    _customerRepository = customerRepository;
  }
  public override Customer {
    get {
      if(base.Customer == null)
        Customer = _customerRepository.Get(CustomerId);
      return base.Customer
    }
    set { base.Customer = value; }
  }
}
public class ProductRepository : IProductRepository {
  public Product Get(int id) {
    var dr = GetDataReaderForId(id);
    return new ProductLazyLoadProxy() {
      Id = Convert.ToInt(dr["id"]),
      CustomerId = Convert.ToInt(dr["customer_id"]),
    }
  }
}

但在写了大约20篇之后我就放弃了并学习了NHibernate,Linq2NHibernate用于查询,而FluentNHibernate用于配置,现在路障比以往任何时候都要低.

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有