C# 如何创建一个与SQLServer和SQLite兼容的DbCommand,而不需要很大的条件?

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

嗨,假设我有一个C代码

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;
}