我不喜欢Entity Framework或LINQ,而且我是一名通过帮助班使用旧方法的老学程序员。
以下是我将数据插入数据库的一种方法示例。
private class Database
{
public static void DbInsert(string table, string[] columnNames,
string[] dataToAdd)
{
string tblValues = "";
string tblRaw = "";
string tblValuesCN = "";
string test = "";
string sql = "";
SqlConnection sqlConn = new SqlConnection();
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
sqlConn.ConnectionString = ConnectionString();
for (int i = 0; i < dataToAdd.Length; i++)
{
sqlCmd.Parameters.Add(new SqlParameter("@" + i.ToString(),
dataToAdd[i].ToString()));
test += dataToAdd[i].ToString() + " --- ";
tblValues = tblValues + "@" + i.ToString();
tblRaw = tblRaw + dataToAdd[i].ToString();
if (i != dataToAdd.Length - 1)
{
tblValues = tblValues + ",";
tblRaw = tblRaw + ",";
}
}
for (int i = 0; i < columnNames.Length; i++)
{
tblValuesCN = tblValuesCN + columnNames[i].ToString();
if (i != columnNames.Length - 1)
{
tblValuesCN = tblValuesCN + ",";
}
}
sqlCmd.CommandTimeout = 0;
sqlCmd.CommandText = "Insert Into " + table + "(" + tblValuesCN +
") Values (" + tblValues + ")";
sql = "Insert Into " + table + "(" + tblValuesCN +
") Values (" + tblRaw + ")";
sqlConn.Open();
sqlCmd.Connection = sqlConn;
sqlCmd.ExecuteNonQuery();
sqlConn.Close();
sqlConn.Dispose();
sqlCmd.Dispose();
string[] tlCn = {"TableName", "PatientID", "StaffID", "SQL", "DateTime"};
string[] tlCv =
{
table, HttpContext.Current.Session["PatientID"].ToString(),
HttpContext.Current.User.Identity.Name.ToString(),
sql, DateTime.Now.ToString()
};
DbInsertTL("TransactionLog", tlCn, tlCv);
}
}
现在我开始怀疑,这是安全的,因为该方法是静态的吗?我开始怀疑是因为一次投诉,他们没有添加的内容是来自其他用户的数据库。
我讨厌使用这个类的静态方法从网页后面的代码中实例化所有内容,但是我会尽我所能来保持完整性。
答案 0 :(得分:4)
有些东西是安全的,直到一些资源可能被一个以上的线程访问,或者一个或多个线程正在访问应该明确处理的非托管资源,或者它们可以保持锁定以死锁结束。
现在假设您将SqlConnection
声明为静态字段,并且方法处理它,而其他HTTP请求中的其他要求即将执行命令... CRASH !! 。您需要同步对SqlConnection
实例的访问权限。您甚至可以实现连接池或其他任何东西(好吧,SQL Server已经有连接池,这只是一个例子)。
在您的情况下,最可能的不安全代码之一,但与它包含在静态方法中的事实无关,是您创建SqlConnection
并且不使用using
语句的地方,这提供了更多的安全性,因为您完全保证在结束using
块之后将其处理:
// Equivalent to try/finally where finally
// block will implicitly call SqlConnection.Dispose() for you
// even if some exception is thrown within the using block
using(SqlConnection conn = ...)
{
}
您可能会创建非公开的SQL连接,并且您可能最终会过度使用SQL Server连接池,或者只是因为没有更多连接可用而导致应用程序崩溃...
无论如何,我怀疑你的论点“我喜欢静态方法,因为我讨厌实例化类”正在推动你朝着正确的方向发展。
C#是一种完整的面向对象编程语言,您应该创建对象图,并以面向对象的方式分离您的关注点 - 也就是说,您应该避免使用类作为函数模块 - 。
也许你应该看看façade设计模式。这种模式可以创建一个可以简化复杂事物的类。
例如,您需要注册用户,这意味着实例化一些域类。由于注册用户是一个用例,您可以简化它实现可能具有UserFacade
方法的RegisterUser
,这将执行该域操作,因此赢得更高级别的层我们需要重复相同的代码,他们将对低级域名详细信息保持不可知......
你会实例化console.write吗?它以类似的方式使用
是的,对,有一些辅助类,它们是作为静态类实现的。
你的情况对于静态类来说听起来不好,因为每个方法都在重复代码来创建SQL连接和其他可以封装并在任何地方使用的细节,以避免代码重复(复制粘贴编程......)。 p>
您可能每次都打开和关闭连接,并且您失去了分批连接或发送命令的机会。
如果你尝试使用静态类来实现上述建议,你会以一堆不可维护的方法和spaguetti代码结束,因为缺乏关注点分离...或者,至少,我们不会谈论一个面向对象的解决方案......
您可能会使用静态类。例子:
帮助程序类(不是你的情况......你的情况是一个低级数据访问层,如果你坚持使用C#,应该使用面向对象的方法实现)。
扩展方法。
工厂方法。
...