cn = new SqlConnection(
ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
cn.Open();
假设我有内容页面和母版页,这段代码应该放在哪里?
我应该将它放在母版页Page_Init
中吗?那么在我的内容页面上的每个执行阶段都可以完全访问它吗?
我习惯于经典ASP,所以我通常会这样做:
Declare variables
Open connection
process code
Close connection
Render HTML
但是.net中的页面生命周期有很多阶段,所以我想知道放置这段代码的最佳位置是什么?
此连接是否需要关闭,还是垃圾处理会为我处理?
答案 0 :(得分:6)
对于我来说,id创建一个DataAccess层,以便我可以删除代码隐藏文件中的数据库连接。然后我的webapp将引用Dal并公开一个允许来自前端的Dal交互的公共方法
在打开和关闭Dal连接方面 - 将其包装在using语句中 - 在需要时负责打开和关闭连接。
有关此内容的更多信息,请访问此处 - http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx
答案 1 :(得分:3)
我也会选择数据访问层,但为了更直接地回答你的问题,这里是我如何在ASP.NET中执行此操作,同时处理事务。
如果出现问题,我还会添加一个用于请求事务回滚的VoteRollback()
方法。页面执行继续(您必须通过代码处理问题)但是当页面被卸载时,事务将被回滚
答案 2 :(得分:2)
在.Net中,它取决于您使用的结构。如果通过手动使用SqlConnection对象显式连接,则需要直接管理其连接。如果您使用数据集tableadapter对象或带有LINQ的DataContext对象(我的个人建议),通常会为您管理连接,但您需要将对象封装在使用块中以确保正确收集它。
我们团队对“最佳实践”的考虑是构建一个通用数据管理器,在我们的公共数据类中实现IDisposable,该数据类处理任何基于连接的对象的延迟加载以检索数据。这样,我们可以强制关闭该数据管理器的dispose事件中的任何连接,以保持其清洁。
修改强>
我总是从格思里开始 http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
下面是我的标准BaseDataManager的代码示例。我很可能很久以前就已经为它创建了一个界面,但是抽象的一点似乎让我的其他团队成员能够很好地采用它。我发布这个代码没有保修,但它适用于我,它使我的连接池保持良好和干净(我们对存储在数据库中的文档信息进行了大量的数据提取)。我删除了许多其他基本方法以保持简单,以下是直接回答您问题的部分:
[Serializable()]
public abstract class BaseDataManager : IDisposable
{
private bool _disposedValue = false;
private SqlConnection _connectionObject = null;
public BaseDataManager()
{
}
public BaseDataManager(string connectionString)
{
this.SqlConnectionString = connectionString;
}
public BaseDataManager(string connectionString, string username, string password)
{
if (!connectionString.EndsWith(";")) connectionString += ";";
this.SqlConnectionString += "User ID=" + username + ";password=" + password;
}
public string SqlConnectionString
{
get;
set;
}
public virtual SqlConnection Connection
{
get
{
if (_connectionObject == null && !String.IsNullOrEmpty(this.SqlConnectionString))
_connectionObject = new SqlConnection(this.SqlConnectionString);
return _connectionObject;
}
set
{
_connectionObject = value;
}
}
#region IDisposable Support
/// <summary>
/// (Protected) Method that performs actual cleanup on dispose. This interface
/// has been implemented to clean up data connections that are left stranded
/// when the class is disposed while the connection possibly remains open in
/// the connection pool. This opportunity is also used to free up the private
/// variables of the class.
/// </summary>
/// <param name="disposing">Used for explicitly calling Dispose</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
//---------------------------------------------------------------------------------------------
// Close the connection object prior to setting it to nothing
//---------------------------------------------------------------------------------------------
if (_connectionObject != null) _connectionObject.Close();
_connectionObject = null;
}
_disposedValue = true;
}
}
/// <summary>
/// (Public) Method that implements IDisposable. This code is autogenerated
/// the implementation interface in the VS IDE. Do not change this code.
/// </summary>
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
答案 3 :(得分:2)
我建议您创建一个单独的类库项目,该项目公开与数据库中的表相关的类。然后提出对该项目的引用,然后离开。要简化打开/关闭连接,编写类等,请查看Subsonic,它将为您映射所有表,然后您可以在代码隐藏中执行类似的操作。
Product prod = Product.Find(3);
prod.Name = "iPhone";
prod.Save();
答案 4 :(得分:1)
只有在需要数据库中的数据时才应该使用它。
如果您没有创建DAL图层,那么您可以将此事件视为page_load或onClick事件。您不应仅仅为了在页面上打开连接而打开连接。
用于打开连接的代码片段
SqlConnection conn = null
try
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);
conn.Open()
// do something with the connection
}
catch(Exception ex)
{
//log error
}
finally
{
// clean up connection
if(conn!=null)
{
//check if connetion is open, if it is close it / dispose
}
}
答案 5 :(得分:1)
规则的第一个拇指,将Domain层与ASP.NET细节/ View分离。
很多人为Domain层创建一个类库,这样就可以保证Page / View相关的代码不会与它混合。
因此,您将拥有一个域层,您可以在其中使用User,Comment等等类......这些类将与数据库通信。我通常有一个DbUser类,其中发生所有数据库交互,DbUser继承DbQuery,它为您创建连接。这样我就可以将数据库交互代码完全保存到Db {ClassName}类和DbQuery中。如果你想保持代码真正有条理,它真的会有所帮助。
简单场景:
当我收到查看特定用户的个人资料的页面请求时,我只需执行User.GetUser(id);
,其中id是用户的用户ID。 User类有一个静态方法GetUser,它创建一个新的DbUser实例并在那里调用getUser方法。 DbUser中的getUser方法创建一个连接和一个查询到数据库,然后它返回一个User的实例,瞧,你就可以得到它。
我希望我的答案可以帮助你朝着正确的方向前进,虽然这可能有点偏离主题。
更新:通过将域层与网站分离,您可以有更多选项,例如将类库重新用于与同一数据库交互的另一个项目。