开发者

LINQ-To-SQL Business-Layer Object DataContext

开发者 https://www.devze.com 2022-12-18 10:07 出处:网络
Originally, I was using my DataContext object as a global singleton.When using this in ASP.Net, I was running into issues with contention because of the multi-threaded nature of ASP.Net.

Originally, I was using my DataContext object as a global singleton. When using this in ASP.Net, I was running into issues with contention because of the multi-threaded nature of ASP.Net.

So I did some searching for better alternatives, and found Rick Strahl's post about "per object" scenario. So each of my objects would have a DataContext local to the class.

So I have most of it figured out, but my question comes up when trying to get an instance of the object. Since all of the methods are instance methods, I need to get an instance of the Class first. Then I can use that instance to call the instance method to get the object that I want.

Something like this..

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

This just seems redundant to me to create an instance of the class just to call a method to return the actual instance that I want. Is this the correct way of doing this? I would think there is a different way that still adheres to the methodology that Rick uses in his blo开发者_开发百科g post.

Sample class code:

 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();
      }
 }


To address only the question about redundancy, without commenting on the whole context-per-object philosophy or Rick's code, which I haven't reviewed,

You can eliminate the two lines with

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

Alternatively, create a factory that acts as a static gateway:

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

Not only does this clean up your object creation (now you just call var customer = CustomerFactory.BuildCustomerWithId(1);), but now you can modify the BuildCustomerWithId() method, if necessary, without changing the consuming classes. For example, you might later decide you don't like instantiating the DataContext in the business objects, and you refactor it all out. You can instantiate the DataContext in the factory instead, and you don't have to change any code that calls BuildCustomerWithId(). Static gateway makes unit testing slightly more challenging, but still much easier than instantiating Customer objects directly.

I realize that this doesn't solve the problem of first instantiating and then calling the getter method, but frankly, I don't see that as a problem from a performance standpoint -- only in terms of syntax/readability.


The sample class code doesn't close the connection at all. So it leaves the connetion waiting for the garbage collector to clean it up.

Connections are cheap because they're pooled. For the pool to work efficiently, keep connections open for as short a time as possible. I usually open a connection just to execute a single function, like:

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

The using statement makes sure the connection is returned to the pool when the function returns.


If you don't want to create an instance of a Class to get the instance of the object, you could change the GetCustomer method to 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);
        }
    }
    ...
}

And you can use the method like this:

Customer cust = Customer.GetCustomer(primaryKeyID);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号