帮酷LOGO
  • 显示原文与译文双语对照的内容
文章标签:ioc  DES  pattern  optimistic  patterns  设计模式  Concurrency  design-pattern  


介绍

我的上一篇文章展示了使用PostgreSQL数据库的开放式并发。 我想用设计 Pattern IOC和DI编写一个 C# 程序,这样我们就可以支持多个数据库。 这里版本还使用参数化查询和事务。

背景

可以在设计 Pattern IOC和 DI 中详细阅读由 Shivprasad Koirala编写的IOC设计 Pattern 。

使用代码

就像在koirala的Shivprasad文章中描述的那样,我有一个 abstractiDatabase,它是实际的数据库类从。 我只实现了 Postgres,另一个可以是 sql server或者任何其他数据库。

classIOCDI.gif

abstract 类中,我设置了需要在派生类中实现的方法。 因为它是一个 abstract 类而不是 interface,所以在这个类中有一些代码。

publicabstractclass iDatabase
{
 string strdbName; // the database namestring strServer; // the database namestring struserName; // the user namestring strpassword; // the passwordstring strSAName; // the SA user namestring strSApassword; // the SA passwordpublic iDatabase()
 {
 strdbName = ""; // the database name strServer = ""; // the database name struserName = ""; // the user name strpassword = ""; // the password strSAName = ""; // the SA user name strSApassword = ""; // the SA password }
 publicabstractvoid CheckDBConnectionInfo();
 publicabstractstring GetUserPassword(string userName);
 publicabstractint UpdateUser(UserData ud);
 publicabstractint AddUser(string userName, string Password, string ModUser);
 publicabstract UserData GetUser(string userName);
}

postgres 类中更新用户代码是一个普通代码,就像你所期望的。 如果选择 PostreSQL,则运行并更新用户表的代码。 主要的区别是该代码处理乐观并发,并返回数据库记录的整个数据类,而不是每个数据项。

publicoverrideint UpdateUser(UserData ud)
{
 string sqlstring;
 int iret = -1;
 bool errflg = false;
 Object result;
 //// get the connection string// sqlstring = GetConnectionString();
 NpgsqlConnection conn = new NpgsqlConnection(sqlstring);
 conn.Open();
 // create a transaction object NpgsqlTransaction trano = conn.BeginTransaction();
 // set the sql command// uuid, int, str, str, str sqlstring = "Update_MinUser(:Arg1, :Arg2, :Arg3, :Arg4, :Arg5)";
 NpgsqlCommand command = new NpgsqlCommand(sqlstring, conn, trano);
 command.CommandType = CommandType.StoredProcedure;
 try {
 // Now add the parameter to the parameter collection of the command// specifying its type. command.Parameters.Add(new NpgsqlParameter("Arg1", DbType.Guid));
 // Now, add a value to it and later execute the command as usual. command.Parameters[0].Value = ud.UserId;
 // Now add the parameter to the parameter collection of the command// specifying its type. command.Parameters.Add(new NpgsqlParameter("Arg2", DbType.Int16));
 // Now, add a value to it and later execute the command as usual. command.Parameters[1].Value = ud.UserConcur;
 // Now add the parameter to the parameter collection of the command// specifying its type. command.Parameters.Add(new NpgsqlParameter("Arg3", DbType.String));
 // Now, add a value to it and later execute the command as usual. command.Parameters[2].Value = ud.UserName;
 // Now add the parameter to the parameter collection of the command// specifying its type. command.Parameters.Add(new NpgsqlParameter("Arg4", DbType.String));
 // Now, add a value to it and later execute the command as usual. command.Parameters[3].Value = ud.UserPassword;
 // Now add the parameter to the parameter collection of the command// specifying its type. command.Parameters.Add(new NpgsqlParameter("Arg5", DbType.String));
 // Now, add a value to it and later execute the command as usual. command.Parameters[4].Value = ud.ModUser;
 }
 catch (NpgsqlException nex)
 {
 trano.Rollback();
 thrownew Exception(nex.Message);
 }
 try {
 result = command.ExecuteScalar();
 }
 catch (NpgsqlException nex)
 {
 trano.Rollback();
 thrownew Exception(nex.Message);
 }
 finally {
 if (!errflg)
 {
 trano.Commit();
 }
 conn.Close();
 }
 iret = (int)result;
 return (iret);
}

我选择的数据库类型在 clsUser 类中,如下所示。 如果我想在运行时更改数据库类型,我应该检查某个位置并执行 if 语句来创建所需的类。

public ClsUser()
{
 idb = new Postgres();
 idb.DBName = "CONNC";
 idb.Server = "localhost";
 idb.SAUserName = "postgres";
 idb.SAPassword = "Password1";
}

使用代码是非常简单和干净的。 在这个程序中,我添加了一个用户以防它还没有添加。 然后我得到用户数据记录。 然后我更新密码并调用更新程序。 由于仍然有原始数据,我再次调用更新过程来查看发生了什么。 如你所料,由于该记录已经更新,我得到了一个错误。

UserData ud1;int ires;
ClsUser ccus;
ccus = new ClsUser();// do a try catch since we may have run this once beforetry{
 ires = ccus.AddUser("User1", "User1p", "Don");
}catch (Exception ex)
{
 MessageBox.Show("Error from {0}" + ex.Message, "test");
}// get the user dataud1 = ccus.GetUser("User1");// change the password.ud1.UserPassword = "NewPassword";// update the data.ires = ccus.UpdateUser(ud1);if (ires!= 0)
{
 MessageBox.Show("Error updating the user record.");
}// now with the original data try and update it again. It should give us an error.// this will happen since the Optimistic Concurrency has already been updated.// change the password.ud1.UserPassword = "NewPassword1";// update the data.ires = ccus.UpdateUser(ud1);if (ires!= 0)
{
 MessageBox.Show("Error updating the user record the second time.");
}

Points of Interest

从这个设计 Pattern 中获取一个项目是很多工作和代码,支持使用两个或者多个数据库。 如果你知道你不会支持它的他数据库,那么还有它的他模式可以能更好。 zip文件中的Db1.sql 是创建这个项目的表所必需的SQL文件。 作为响应用户输入的一部分,我修改了代码以支持参数化的查询和事务。 为此,我发现Npgsql版本 1不支持所有的uuid 。 我必须下载最新版本 2.

历史记录

  • 第九个 2009年02月 - 初始版本
  • 23rd 2009年02月 - 更新参数化查询,事务


文章标签:DES  设计  pattern  patterns  design-pattern  设计模式  Concurrency  ioc  

Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语