【问题标题】:IRepository confusion on objects returnedIRepository 对返回对象的混淆
【发布时间】:2009-02-07 21:13:28
【问题描述】:

我有一些我经常使用的电子商务代码,它使用 Linq To SQL 将订单保存到数据库。我想删除紧密耦合的 Linq to SQL 位并传入一个 IRepository,但我还是有点困惑。

假设我的 ICustomerRepository 上有一个 GetCustomer() 方法,该方法返回一个 Customer 对象。

我是否需要它来真正返回从该方法传回的 ICustomer 对象,所以如果我从 Linq To SQL 切换到说 SubSonic 这不是问题?

我相信我会这样做,如果是这种情况,Linq To SQL 中是否有一种方法可以轻松地将我的 Linq To SQL Customer 对象转换为我的 ICustomer 对象,例如 SubSonics ExecuteSingle(Of ) 方法?

【问题讨论】:

    标签: asp.net repository-pattern irepository


    【解决方案1】:

    如果您希望您的 Customer 类是一个没有附加到 LINQ 的普通对象,那么您很可能需要编写一个映射器方法来将基于 LINQ 的 Customer 对象转换为您的普通 Customer 域对象。 LINQ to SQL 没有内置这样的功能。

    我已经开始将我的映射方法包装在一个扩展方法中以提高可读性,这确实有助于保持存储库代码的简单。例如,一个示例 CustomerRepository 方法我看起来像:

    public Customer GetById(int id)
    {
       return dataContext.LINQCustomers.Where(c => c.Id == id)
                                       .Single()
                                       .ToDomainObject();
    }
    

    并且 ToDomainObject() 方法是在扩展方法中定义的,例如:

    public static class ObjectMapper
    {
        public static Customer ToDomainObject(this Customer linqObject)
        {
            var domainObject = null
            if (linqObject != null)
            {
                domainObject = new Customer
                {
                   Id = linqObject.Id,
                   FirstName = linqObject.FirstName,
                   LastName = linqObject.LastName
                }
            }
            return domainObject;
        }
    }
    

    或类似的东西。您可以执行相同的操作将域对象转换回 LINQ 对象以传回存储库以实现持久性。

    【讨论】:

    • 我不知道你必须用 LINQ 来做这件事,我以为它只会返回一个客户。 PS:此外,您首先要检查实例是否已加载到本地缓存中。如果是,则返回它,如果不是,则 fetch + cache + return。
    • 可以直接返回 LINQ 生成的“客户”对象,但它也将包含所有 LINQ 生成的持久性逻辑。如果您希望您的存储库返回一个不包含所有 LINQ 内容的普通对象,您必须自己创建一个并映射到它。
    • 看起来像一个 PITA,如果有一种简单的方法可以将它们相互转换(可能使用反射和匹配属性和泛型),那就太好了
    • Max,也许 AutoMapper 与您正在寻找的类似:codeplex.com/AutoMapper
    【解决方案2】:

    只要 Customer 是一个普通的旧 .NET 对象,而不是某个 db 生成的实体,您就可以让它返回一个 Customer。您的 Customer 域对象不应该知道如何(或是否)将其持久化到数据库中,而这应该从您的存储库中返回。在您的存储库中,您可能有一些映射代码 - 这很常见 - 从 [但是您从其存储位置获取数据] 映射到您的域对象。如果您使用的是 Linq-to-sql,那么此映射将来自 Linq-To-Sql 生成的 Customer 表(可能还有其他表 - 您的 Customer 域对象可能不会 1:1 映射到数据库中的特定表) 到您的客户域对象,该对象将存在于不同的命名空间(很可能是程序集)中。

    【讨论】:

      【解决方案3】:

      根本没有必要将其设为 ICustomer。存储库的作用是使它看起来好像您的持久实例在内存中。

      public interface ICustomerRepository
      {
        Customer GetByID(int id);
        IEnumerable<Customer> GetByName(string name);
        Customer GetByVatCode(string vatCode);
      }
      

      有些人会额外包含诸如

      之类的方法
      void Add(Customer newCustomer);
      void Delete(Customer deleted);
      void Update(Customer modified);
      

      后一种方法实现很可能只是更新一个工作单元。

      尽管概念是这些只是请求客户实例的常见方式,但存储库充当请求它们的一种方式,而无需定义如何请求它们。

      【讨论】:

      • 所以 ICustomerRepository 上的 Customer 是否由 Linq To SQL 或 SubSonic 创建并且类型可能不同是否重要?
      • 客户在您的 ICustomerRepository 中的何处定义?
      • Max - 为什么它们的类型会不同?客户就是客户,当您要求客户时,这就是您应该得到的。
      • 客户类别将在您的业务模型(您的领域层)中定义
      猜你喜欢
      • 2017-01-11
      • 1970-01-01
      • 2010-11-30
      • 2012-07-30
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多