C# 如何创建一个与SQLServer和SQLite兼容的DbCommand,而不需要很大的条件?
嗨,假设我有一个C代码C# 如何创建一个与SQLServer和SQLite兼容的DbCommand,而不需要很大的条件?,c#,sql,.net,sql-server,sqlite,C#,Sql,.net,Sql Server,Sqlite,嗨,假设我有一个C代码 private const string INSERT=“插入个人值(@FirstName,@LastName)”; 公共静态DbCommand INSERTCOMMAND(IPerson个人) { DbCommand=null; var sqlParams=新列表(); if(SQLManagerFactory.SQLManager是SQLServerManager) { 命令=新的SqlCommand(插入); 添加(新的SqlParameter(“@FirstNam
private const string INSERT=“插入个人值(@FirstName,@LastName)”;
公共静态DbCommand INSERTCOMMAND(IPerson个人)
{
DbCommand=null;
var sqlParams=新列表();
if(SQLManagerFactory.SQLManager是SQLServerManager)
{
命令=新的SqlCommand(插入);
添加(新的SqlParameter(“@FirstName”,person.FirstName);
添加(新的SqlParameter(“@LastName”,person.LastName);
}
else//SQLiteManager
{
命令=新的SQLiteCommand(插入);
添加(新的SQLiteParameter(“@FirstName”,person.FirstName);
添加(新的SQLiteParameter(“@LastName”,person.LastName);
}
AddRange(sqlParams.ToArray());
返回命令;
}
当然,在我的产品代码中,它更大,有更多的位置,可以为不同的命令做类似的事情
我的问题是,有没有办法缩短这个过程?我不希望复制和粘贴代码,这些代码除了调用不同的构造函数外,基本上做相同的事情
提前非常感谢。像这样的东西就可以了,我省略了细节,但你可以弄清楚:
private const string INSERT = "INSERT INTO Person VALUES (@FirstName, @LastName)";
public static DbCommand INSERTCOMMAND(IPerson person)
{
DbCommand command = null;
var sqlParams = new List<DbParameter>();
MySqlEnum sqlType = SQLManagerFactory.SQLManager is SQLServerManager ? MySqlEnum.SQLServer : MySqlEnum.sqlLite
if(sqlType == MySqlEnum.SQLServer)
command = new SqlCommand(INSERT);
else // SQLiteManager
command = new SQLiteCommand(INSERT);
sqlParams.Add(new CustomSqlParameter(sqlType ,"@FirstName", person.FirstName);
sqlParams.Add(new CustomSqlParameter(sqlType ,"@LastName", person.LastName);
command.Parameters.AddRange(sqlParams.ToArray());
return command;
}
private const string INSERT=“插入个人值(@FirstName,@LastName)”;
公共静态DbCommand INSERTCOMMAND(IPerson个人)
{
DbCommand=null;
var sqlParams=新列表();
MySqlEnum sqlType=SQLManagerFactory.SQLManager是SQLServerManager吗?MySqlEnum.SQLServer:MySqlEnum.sqlLite
if(sqlType==MySqlEnum.SQLServer)
命令=新的SqlCommand(插入);
else//SQLiteManager
命令=新的SQLiteCommand(插入);
添加(新的CustomSqlParameter(sqlType,“@FirstName”,person.FirstName);
添加(新的CustomSqlParameter(sqlType,“@LastName”,person.LastName);
AddRange(sqlParams.ToArray());
返回命令;
}
CustomSqlParameter的代码应该是显而易见的类似于这样的代码就可以了,我省略了细节,但您可以找出这些细节:
private const string INSERT = "INSERT INTO Person VALUES (@FirstName, @LastName)";
public static DbCommand INSERTCOMMAND(IPerson person)
{
DbCommand command = null;
var sqlParams = new List<DbParameter>();
MySqlEnum sqlType = SQLManagerFactory.SQLManager is SQLServerManager ? MySqlEnum.SQLServer : MySqlEnum.sqlLite
if(sqlType == MySqlEnum.SQLServer)
command = new SqlCommand(INSERT);
else // SQLiteManager
command = new SQLiteCommand(INSERT);
sqlParams.Add(new CustomSqlParameter(sqlType ,"@FirstName", person.FirstName);
sqlParams.Add(new CustomSqlParameter(sqlType ,"@LastName", person.LastName);
command.Parameters.AddRange(sqlParams.ToArray());
return command;
}
private const string INSERT=“插入个人值(@FirstName,@LastName)”;
公共静态DbCommand INSERTCOMMAND(IPerson个人)
{
DbCommand=null;
var sqlParams=新列表();
MySqlEnum sqlType=SQLManagerFactory.SQLManager是SQLServerManager吗?MySqlEnum.SQLServer:MySqlEnum.sqlLite
if(sqlType==MySqlEnum.SQLServer)
命令=新的SqlCommand(插入);
else//SQLiteManager
命令=新的SQLiteCommand(插入);
添加(新的CustomSqlParameter(sqlType,“@FirstName”,person.FirstName);
添加(新的CustomSqlParameter(sqlType,“@LastName”,person.LastName);
AddRange(sqlParams.ToArray());
返回命令;
}
CustomSqlParameter的代码在设计和可测试性方面应该是显而易见的,我认为在您的示例中进行耦合是不对的 假设只有一个数据库发生了更改,而您需要更改INSERT查询,这将导致问题,因为相同的查询用于其他数据库 实际上,您可以创建
PersonRepository
抽象:
公共接口IPersonRepository
{
无效添加(个人)
}
并创建该接口的两个实现:
公共SqlServerPersonRepository:IPersonRepository
{
无效添加(个人)
{
//sql server特定代码
}
}
公共SqlLitePersonRepository:IPersonRepository
{
无效添加(个人)
{
//sqlite特定代码
}
}
在设计和可测试性方面,我认为像您的示例中那样进行耦合是不对的 假设只有一个数据库发生了更改,而您需要更改INSERT查询,这将导致问题,因为相同的查询用于其他数据库 实际上,您可以创建
PersonRepository
抽象:
公共接口IPersonRepository
{
无效添加(个人)
}
并创建该接口的两个实现:
公共SqlServerPersonRepository:IPersonRepository
{
无效添加(个人)
{
//sql server特定代码
}
}
公共SqlLitePersonRepository:IPersonRepository
{
无效添加(个人)
{
//sqlite特定代码
}
}
将特定于数据库的知识移动到
SQLManager
类中(或创建自己的类来包装它):
publicstaticdbcommand插入命令(IPerson-person)
{
var sqlParams=新列表();
var sql=SQLManagerFactory.SQLManager;//或MyOwnSQLManager
var command=sql.CreateCommand(插入);
sqlParams.Add(sql.CreateParameter(“@FirstName”,person.FirstName));
sqlParams.Add(sql.CreateParameter(“@LastName”,person.LastName));
AddRange(sqlParams.ToArray());
返回命令;
}
将特定于数据库的知识移动到SQLManager
类中(或创建自己的类来包装它):
publicstaticdbcommand插入命令(IPerson-person)
{
var sqlParams=新列表();
var sql=SQLManagerFactory.SQLManager;//或MyOwnSQLManager
var command=sql.CreateCommand(插入);
sqlParams.Add(sql.CreateParameter(“@FirstName”,person.FirstName));
sqlParams.Add(sql.CreateParameter(“@LastName”,person.LastName));
AddRange(sqlParams.ToArray());
返回命令;
}
我对SQL Lite不太了解,但单独创建一个过程并调用它们创建一个自定义类,用于处理参数和循环的传递。在InsertCommand上使用Facade模式和/或将参数创建包装为类似(CreateParam)的形式,并在此处进行检查
public static DbCommand INSERTCOMMAND(IPerson person)
{
var sqlParams = new List<DbParameter>();
var sql = SQLManagerFactory.SQLManager; // or MyOwnSQLManager
var command = sql.CreateCommand(INSERT);
sqlParams.Add(sql.CreateParameter("@FirstName", person.FirstName));
sqlParams.Add(sql.CreateParameter("@LastName", person.LastName));
command.Parameters.AddRange(sqlParams.ToArray());
return command;
}