最初,我使用的是DataContext对象作为全局单例。在ASP.Net中使用它时,由于ASP.Net的多线程特性,我遇到了争用问题。
所以我做了一些寻找更好的替代方案,并找到了关于“每个对象”场景的Rick Strahl's post。所以我的每个对象都有一个本地的DataContext。
所以我已经弄明白了,但是在尝试获取对象的实例时,我的问题出现了。由于所有方法都是实例方法,因此我需要先获取Class的实例。然后我可以使用该实例调用实例方法来获取我想要的对象。
像这样......
Customer cust = new Customer();
cust = cust.GetCustomer(primaryKeyID); // gets data using LINQ-To-SQL
这对我来说似乎是多余的,只是为了调用一个方法来返回我想要的实际实例而创建一个类的实例。这是正确的做法吗?我认为有一种不同的方式仍然坚持Rick在他的博客文章中使用的方法。
示例类代码:
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();
}
}
答案 0 :(得分: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()
的代码。静态网关使单元测试更具挑战性,但仍然比直接实例化Customer
对象容易得多。
我意识到这并没有解决首次实例化然后调用getter方法的问题,但坦率地说,从性能的角度来看,我不认为这只是一个问题 - 只是在语法/可读性方面。 / p>
答案 1 :(得分:1)
示例类代码根本不会关闭连接。所以它让连接等待垃圾收集器清理它。
连接很便宜,因为它们是合并的。为了使池有效工作,请尽可能短的时间保持连接打开。我通常只是为了执行一个函数而打开一个连接,如:
using (MyDataContext db = new MyDataContext(conStr))
return db.Customers.SingleOrDefault(c => c.ID == custID);
using语句确保在函数返回时将连接返回到池中。
答案 2 :(得分: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);