代码之家  ›  专栏  ›  技术社区  ›  Ryan Alford

Linq to SQL业务层对象DataContext

  •  2
  • Ryan Alford  · 技术社区  · 15 年前

    最初,我使用DataContext对象作为全局单例。在ASP.NET中使用它时,由于ASP.NET的多线程特性,我遇到了争用问题。

    所以我做了一些寻找更好的选择,并发现 Rick Strahl's post 关于“每对象”场景。所以我的每个对象都有一个类的本地DataContext。

    所以我已经解决了其中的大部分问题,但是当我试图得到一个对象的实例时,我的问题出现了。因为所有的方法都是实例方法,所以我需要首先获取类的一个实例。然后我可以使用该实例调用实例方法来获取我想要的对象。

    像这样的……

     Customer cust = new Customer();
     cust = cust.GetCustomer(primaryKeyID); // gets data using LINQ-To-SQL
    

    在我看来,创建类的实例只是为了调用一个方法来返回我想要的实际实例是多余的。这是正确的方法吗?我认为有一种不同的方式仍然坚持里克在他的博客中使用的方法。

    示例类代码:

     public partial class Customer
     {
          MyDataContext db = new MyDataContext(Settings.MyConnectionString);
    
          public Customer GetCustomer(Int64 custID)
          {
               return db.Customers.SingleOrDefault(c => c.ID == custID);
          }
    
          public Customer AddCustomer(Customer c)
          {
               db.Customers.InsertOnSubmit(c);
               db.SubmitChanges();
          }
     }
    
    3 回复  |  直到 15 年前
        1
  •  2
  •   Jay    15 年前

    只解决关于冗余的问题,而不评论每个对象哲学或Rick的代码的整个上下文,我没有评论过这些内容,

    你可以用

    var customer = new Customer().GetCustomer(primaryKeyId);
    

    或者,创建一个充当静态网关的工厂:

    public static class CustomerFactory
    {
       public static Customer BuildCustomerWithId(_<int/short/long>_ primaryKeyId)
       {
          var customer = new Customer();
          return customer.GetCustomer(primaryKeyId);
       }
    }
    

    这不仅清理了对象创建(现在您只需调用 var customer = CustomerFactory.BuildCustomerWithId(1); ,但现在可以修改 BuildCustomerWithId() 方法,如果需要,不更改消费类。例如,稍后您可能会决定不喜欢在业务对象中实例化DataContext,然后将其全部重构。您可以在工厂中实例化DataContext,而不必更改任何调用 BuildCustomerWithID()生成 .静态网关使单元测试稍微更具挑战性,但仍然比实例化容易得多。 Customer 直接对象。

    我意识到这并不能解决先实例化然后调用getter方法的问题,但坦率地说,我不认为这是从性能的角度来看的问题——只是在语法/可读性方面。

        2
  •  1
  •   Andomar    15 年前

    示例类代码根本没有关闭连接。所以它离开连接等待垃圾收集器清理它。

    连接很便宜,因为它们是集合在一起的。为了使池有效工作,请尽可能短时间保持连接打开。我通常只打开一个连接来执行一个函数,比如:

    using (MyDataContext db = new MyDataContext(conStr))
        return db.Customers.SingleOrDefault(c => c.ID == custID);
    

    using语句确保在函数返回时将连接返回到池。

        3
  •  1
  •   ferpaz    15 年前

    如果不想创建类的实例来获取对象的实例,可以将getCustomer方法更改为static。

    public partial class Customer
    {
        public static Customer GetCustomer(Int64 custID)
        {
            using (var db = new MyDataContext(Settings.MyConnectionString))
            {
                return db.Customers.SingleOrDefault(c => c.ID == custID);
            }
        }
        ...
    }
    

    你可以用这样的方法:

    Customer cust = Customer.GetCustomer(primaryKeyID);