更高效的数据库访问

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

DataClassesDataContext db = new DataClassesDataContext() 

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

现在,两个有趣的查询:

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

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

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

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

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

通常情况是这样的:

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

另外,如果我不在通话中使用,究竟会发生什么?

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

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

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

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

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

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

这就是为什么数据上下文是“在旅途中”创建和处理的原因。 事实上, 类规范明确地提出了这种使用模式:

通常,DataContext实例设计为持续一个“工作单元”,但是您的应用程序定义该术语。 DataContext是轻量级的,创建起来并不昂贵。 典型的LINQ to SQL应用程序在方法范围内创建DataContext实例,或者作为表示相关数据库操作的逻辑集的短期类的成员。

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

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