【问题标题】:How do I create generic SQL parameters in .NET?如何在 .NET 中创建通用 SQL 参数?
【发布时间】:2013-11-21 11:42:49
【问题描述】:

根据Configuring Parameters 上的 Microsoft 文档,“.NET Framework 数据提供程序以不同方式处理命名和指定参数以及参数占位符”。

  • System.Data.SqlClient 使用@parametername 格式的命名参数
  • System.Data.OleDbSystem.Data.Odbc 使用由问号指示的位置参数标记 (?)
  • System.Data.OracleClient 使用:parmname(或parmname)格式的命名参数

我正在编写方法来返回将用于参数化语句的 SQL。如果我使用标准 SQL,这些语句应该可以移植到各种数据库中。如何创建通常有效的参数,而不会将数据提供者的关注点泄漏到 SQL 组件?

【问题讨论】:

  • 我不认为他们有很大的不同。 OleDb 可以识别@field。它的那种普遍性。甲骨文也应该没问题。现在在命令对象中添加参数时,完全可以避免@field前缀,只需添加field
  • PostGre 也适用于 @field。

标签: .net sql ado.net oracleclient


【解决方案1】:

只是避免@并使用 System.Data.SqlClient /System.Data.OracleClient

顺便说一句,如果您希望它可移植,请使用 System.Data.IDbCommand 或 System.Data.Common.DbCommand

使用接口还是抽象类是个人喜好问题。
接口更合适,但是抽象类有一些在接口中不可用的附加方法(例如 DataReader.HasRows)。 我使用了界面,但回想起来,这是一个错误。我应该改用抽象类(System.Data.Common.DbAnything 而不是 System.Data.IAnything)。

您可以为这些编写扩展方法“AddParameter”,也可以将 DAL 转换为抽象类,并添加方法 AddParameter,您可以在其中覆盖相应实例的变量名称。

public abstract class cDAL
{


    // From Type to DBType
    protected virtual System.Data.DbType GetDbType(Type type)
    {
        // http://social.msdn.microsoft.com/Forums/en/winforms/thread/c6f3ab91-2198-402a-9a18-66ce442333a6
        string strTypeName = type.Name;
        System.Data.DbType DBtype = System.Data.DbType.String; // default value

        try
        {
            if (object.ReferenceEquals(type, typeof(System.DBNull)))
            {
                return DBtype;
            }

            if (object.ReferenceEquals(type, typeof(System.Byte[])))
            {
                return System.Data.DbType.Binary;
            }

            DBtype = (System.Data.DbType)Enum.Parse(typeof(System.Data.DbType), strTypeName, true);

            // Es ist keine Zuordnung von DbType UInt64 zu einem bekannten SqlDbType vorhanden.
            // http://msdn.microsoft.com/en-us/library/bbw6zyha(v=vs.71).aspx
            if (DBtype == System.Data.DbType.UInt64)
                DBtype = System.Data.DbType.Int64;
        }
        catch (Exception)
        {
            // add error handling to suit your taste
        }

        return DBtype;
    } // End Function GetDbType


    public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue)
    {
        return AddParameter(command, strParameterName, objValue, System.Data.ParameterDirection.Input);
    } // End Function AddParameter


    public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue, System.Data.ParameterDirection pad)
    {
        if (objValue == null)
        {
            //throw new ArgumentNullException("objValue");
            objValue = System.DBNull.Value;
        } // End if (objValue == null)

        System.Type tDataType = objValue.GetType();
        System.Data.DbType dbType = GetDbType(tDataType);

        return AddParameter(command, strParameterName, objValue, pad, dbType);
    } // End Function AddParameter


    public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue, System.Data.ParameterDirection pad, System.Data.DbType dbType)
    {
        System.Data.IDbDataParameter parameter = command.CreateParameter();

        if (!strParameterName.StartsWith("@"))
        {
            strParameterName = "@" + strParameterName;
        } // End if (!strParameterName.StartsWith("@"))

        parameter.ParameterName = strParameterName;
        parameter.DbType = dbType;
        parameter.Direction = pad;

        // Es ist keine Zuordnung von DbType UInt64 zu einem bekannten SqlDbType vorhanden.
        // No association  DbType UInt64 to a known SqlDbType

        if (objValue == null)
            parameter.Value = System.DBNull.Value;
        else
            parameter.Value = objValue;

        command.Parameters.Add(parameter);
        return parameter;
    } // End Function AddParameter


    public virtual T GetParameterValue<T>(System.Data.IDbCommand idbc, string strParameterName)
    {
        if (!strParameterName.StartsWith("@"))
        {
            strParameterName = "@" + strParameterName;
        }

        return InlineTypeAssignHelper<T>(((System.Data.IDbDataParameter)idbc.Parameters[strParameterName]).Value);
    } // End Function GetParameterValue<T>


}

然后在相应的提供者中覆盖它:

public class cOleDb : cDAL
{




   public overrideSystem.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue)
    {
        strParameterName = "?";
        return AddParameter(command, strParameterName, objValue, System.Data.ParameterDirection.Input);
    } // End Function AddParameter


    // Etc.

}

您可以通过在连接字符串 web.config 条目中读取 provider 来创建相应的类实例。

PS:System.Data.OracleClient 已弃用,请使用 ODP.NET(您仍然需要安装 Oracle 的本机 OracleClient dll [免费下​​载])

【讨论】:

    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    相关资源
    最近更新 更多