更高效的数据库访问

时间:2011-01-16 17:08:55

标签: c# asp.net sql performance linq-to-sql

我是数据库和linq的新手,所以我的问题可能被认为是微不足道的。我目前在每个类中使用以下命令启动所有数据库请求:

 DataClassesDataContext db = new DataClassesDataContext()

然后我继续在方法中做出我需要的任何linq请求,并继续使用主应用程序逻辑。

现在,有两个有趣的问题:

1)我相信我已经看到人们在“使用”中包含数据库使用情况。如:

using (DataClassesDataContext db = new DataClassesDataContext())
{
    ...
}

如果这是正确的,那么这不是说我的类不能再使用成员'db'变量了,而是需要在每个函数调用中进行那些db请求吗?另外,如果我不在通话中使用“使用”,究竟会发生什么?

2)在启用SQL事件探查器的情况下运行我的应用程序,我看到许多连接打开和关闭。这是否意味着每个DataClassesDataContext调用都会建立一个单独的连接?它看起来效率低下,在实际使每个类中使DataClassesDataContext对象成为静态的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

通常,每个数据库对话应使用一个DataContext。只有您可以准确地确定对话是什么,但通常它是一个完整的请求(例如,获取用户的愿望清单,或者获取用户的已关闭订单),您可能会将其视为“工作单元”。

通常情况是这样的:

WishList wishlist;
using(var context = new DataContext(connectionString)) {
    var service = new UserWishListService(context);
    wishlist = service.GetUserWishList();
}
  

另外,如果我不在呼叫中使用using,究竟会发生什么?

DataContext不会被正确处理(除非你已经包裹在try-catch-finally中,但通常你应该只使用using)。

  

这是否意味着每个DataClassesDataContext调用都会建立一个单独的连接?

不完全。您的应用程序将受益于SQL Server ADO.NET提供程序的内置connection pooling。不要担心这一点,让供应商为您管理。

  

这似乎效率低下,在每个使用的类中实际使DataClassesDataContext对象成为static的正确方法是什么?

绝对不是。 DataContext s不是线程安全的(事实上,它们是线程不安全的)并且在它上面写着“有龙”。此外,即使是单线程上下文,static DataContext也是一个糟糕的选择,因为DataContext维护了从数据库中提取的所有实体的缓存(用于对象跟踪)。随着时间的推移,内存消耗将变得巨大。

答案 1 :(得分:1)

由于您添加了asp.net标记,这意味着您正在使用HTTP调用中的上下文。静态成员上下文在asp.net中不可用,因为您需要同步对它的访问,并且由于每次调用都需要您的数据上下文,因此您一次只能提供一个HTTP响应,可扩展性史诗般的惨败。

这就是“移动中”创建和处理数据上下文的原因。实际上,the class specifications明确地提到了这种使用模式:

  

通常,DataContext实例是   旨在持续一个“单位   工作“但你的应用程序定义   那个词。 DataContext是   轻便且不贵   创建。典型的LINQ to SQL   应用程序创建DataContext   方法范围或实例   昙花一现的成员   代表一组相关的逻辑   数据库操作。

对于ASP.Net来说,一个合理的“工作单元”上下文就是HTTP调用本身。有关此主题的更长时间的讨论可以在Linq to SQL DataContext Lifetime Management找到。

连接打开/关闭的问题不是问题。通常,连接是汇集的,“开放”只不过是重用池中的连接。如果您正在打开重量级(完全成熟的登录),那么您正在使用错误的池。比较Logins/secConnection Resets/sec计数器将很快揭示确实是这种情况。