2010-01-24 118 views
2

最初,我使用我的DataContext對象作爲全局單例。當在ASP.Net中使用它時,由於ASP.Net的多線程性質,我遇到了爭用問題。LINQ-to-SQL業務層對象DataContext

所以我做了一些更好的選擇,並找到了關於「每個對象」場景的Rick Strahl's post。所以我的每個對象都有一個DataContext,它是本地的。

所以我大部分都想通了,但是當我試圖獲得對象的一個​​實例時出現了我的問題。由於所有的方法都是實例方法,所以我需要首先獲取類的實例。然後我可以使用該實例調用實例方法來獲取我想要的對象。

事情是這樣的..

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

這完全是多餘的我創建類的實例只是調用一個方法返回,我想實際的實例。這是做這件事的正確方法嗎?我認爲有一種不同的方式仍然堅持裏克在他的博客文章中使用的方法。

Sample類代碼:

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

回答

2

爲了解決大約只有冗餘的問題,不評論對整個上下文的每個對象的哲學或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()的代碼。靜態網關使單元測試更具挑戰性,但仍比直接實例化對象要容易得多。

我意識到這並不能解決第一個實例化並調用getter方法的問題,但坦白地說,從性能的角度來看,我不認爲這是一個問題,只是從語法/可讀性方面來看。

1

樣本類代碼不關閉連接的。所以它留下了等待垃圾收集器的連接來清理它。

連接便宜,因爲它們是合併的。爲了讓游泳池高效工作,請儘可能縮短連接時間。我通常會打開一個連接只是執行單一的功能,如:

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

using語句確保連接返回到池中時,函數返回。

+0

默認情況下,LINQ到SQL打開和關閉它自己的連接。 http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/90dc4a62-7316-4791-9db8-056c21153b84/ 你可以通過評估'db.Connection.State'來測試它。查詢執行後關閉。見圖http://img690.yfrog.com/img690/1577/124201094248am.png – 2010-01-24 14:44:55

+0

@ Eclipsed4utoo:有趣。對'SingleOrDefault()'的調用必須允許。但是,如果你返回一個IEnumerable的中途,我不認爲LINQ會知道足夠的關閉連接。所以使用'使用'是一個好習慣 – Andomar 2010-01-24 15:19:51

1

如果您不想創建一個Class的實例來獲取該對象的實例,則可以將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);