首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何改进这个数据库连接类?(ADO.NET)

如何改进这个数据库连接类?(ADO.NET)
EN

Stack Overflow用户
提问于 2017-10-17 18:59:16
回答 1查看 152关注 0票数 0

我正在尝试创建一个数据库访问层。我正在寻找对这一类/最佳实践的建议的一些改进。如果有人能为我指出如何潜在地完成这一点/需要考虑的事情,那将是很有帮助的。我已经考虑过使用实体框架,但它似乎不适用,然而,我真的应该考虑迁移到EF吗?ADO.NET是一种过时的方式吗?

代码语言:javascript
复制
    public static IDbCommand GetCommandObject(string Connstring)
    {
        IDbConnection conn = new SqlConnection(Connstring);
        return new SqlCommand { Connection = (SqlConnection)conn };
    }

    public static void AddParameter(ref IDbCommand cmd, string Name, object value, DbType ParamType)
    {
        IDbDataParameter Param = cmd.CreateParameter();
        Param.DbType = ParamType;
        Param.ParameterName = (Name.StartsWith("@")) ? "" : "@"; //@ character for MS SQL database
        Param.Value = value;

        cmd.Parameters.Add(Param);
    }

    public static Int32 ExecuteNonQuery(string SQL, IDbCommand cmd = null)
    {
        Boolean CommitTrans = true;
        Boolean CloseConn = true;
        SqlTransaction Trans = null;

        try
        {
            //IF Required - create command object if required
            if (cmd == null) { cmd = DB.GetCommandObject(""); }

            //Add the commandtext
            cmd.CommandText = SQL;

            if (cmd.Connection == null) { throw new Exception("No connection set"); }

            //IF REQUIRED - open the connection
            if (cmd.Connection.State == ConnectionState.Closed)
            {
                cmd.Connection.Open();
            }
            else
            {
                CloseConn = false;
            }

            if (cmd.Transaction != null)
            {
                //We have already been passed a Transaction so dont close it
                CommitTrans = false;
            }
            else
            {
                //Create and open a new transaction
                Trans = (SqlTransaction)cmd.Connection.BeginTransaction();
                cmd.Transaction = Trans;
            }

            Int32 rtn = cmd.ExecuteNonQuery();

            if (CommitTrans == true) { Trans.Commit(); }

            return rtn;
        }
        catch (Exception e)
        {
            if (CommitTrans == true) { Trans.Rollback(); }

            throw new Exception();
        }
        finally
        {
            if (CloseConn == true)
            {
                cmd.Connection.Close();
                cmd = null;
            }

        }

    }

    public static object ExecuteScalar(string SQL, IDbCommand cmd, Boolean NeedsTransaction = true)
    {
        Boolean CommitTrans = true;
        Boolean CloseConn = true;
        SqlTransaction Trans = null;

        try
        {
            //IF Required - create command object if required
            if (cmd == null) { cmd = DB.GetCommandObject(""); }

            //Add the commandtext
            cmd.CommandText = SQL;

            //IF REQUIRED - create default Connection to CourseBuilder DB
            if (cmd.Connection == null) { throw new Exception("No Connection Object"); }

            //IF REQUIRED - open the connection
            if (cmd.Connection.State == ConnectionState.Closed)
            {
                cmd.Connection.Open();
            }
            else
            {
                CloseConn = false;
            }

            if (NeedsTransaction == true)
            {
                if (cmd.Transaction != null)
                {
                    //We have already been passed a Transaction so dont close it
                    CommitTrans = false;
                }
                else
                {
                    //Create and open a new transaction
                    Trans = (SqlTransaction)cmd.Connection.BeginTransaction();
                    cmd.Transaction = Trans;
                }
            }

            Object rtn = cmd.ExecuteScalar();

            if (NeedsTransaction == true && CommitTrans == true) { Trans.Commit(); }

            return rtn;
        }
        catch
        {
            if (NeedsTransaction == true && Trans != null) { Trans.Rollback(); }
            throw new Exception();
        }
        finally
        {
            if (CloseConn == true) { cmd.Connection.Close(); cmd = null; }
        }



    }

    public static DataRow GetDataRow(string SQL, IDbCommand cmd = null, Boolean ErrorOnEmpty = true)
    {
        var dt = FillDatatable(SQL, ref cmd);
        if (dt.Rows.Count > 0)
        {
            return dt.Rows[0];
        }
        else
        {
            if (ErrorOnEmpty == true) { throw new Exception(nameof(GetDataRow) + " returned no rows."); }
            return null;
        }
    }

    public static DataTable FillDatatable(string SQL, ref IDbCommand cmd)
    {

        string newline = System.Environment.NewLine;
        var DT = new DataTable();
        Boolean LeaveConOpen = false;

        try
        {
            //Add the commandtext
            cmd.CommandText = SQL;

            //IF REQUIRED - create default Connection to CourseBuilder DB
            if (cmd?.Connection == null) { throw new Exception("No Connection Object"); }

            if (cmd.Connection.State != ConnectionState.Open)
            {
                cmd.Connection.Open();
                LeaveConOpen = false;
            }
            else
            {
                LeaveConOpen = true;
            }

            var DA = new SqlDataAdapter((SqlCommand)cmd);
            DA.Fill(DT);
        }
        catch (Exception ex)
        {
            var sbErr = new StringBuilder();

            sbErr.AppendLine("Parameters (type defaults to varchar(max)):" + newline);
            foreach (SqlParameter p in cmd.Parameters)
            {
                string s = "";
                sbErr.AppendLine("declare " + p.ParameterName + " varchar(max) = '" + (p.Value == DBNull.Value ? "Null" : p.Value + "'; ") + newline);
            }

            sbErr.AppendLine(newline + SQL + newline);

            throw new Exception("Failed to FillDataTable:" + newline + newline + sbErr.ToString(), ex);

        }
        finally
        {
            if (LeaveConOpen == false) { cmd.Connection.Close(); }

        }

        return DT;

    }

    public static T CheckNull<T>(T value, T DefaultValue)
    {
        if (value == null || value is System.DBNull)
        {
            return DefaultValue;

        }
        else
        {
            return value;
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2017-10-18 01:32:22

创建DAL时需要牢记的几件事

  • DAL应该能够满足多个数据库(oracle、sql、mysql等)的需求。
  • 您应该至少有每个数据库、连接、命令和读取器的实现。
  • 不必担心连接池
  • 请注意事务处理范围,特别是在尝试保存嵌套对象时。(例如:通过保存公司,您可以在单个事务中保存公司、Company.Employees和Employee.Phones )

另一种选择是使用像Dapper这样的东西。

enter image description here

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46788524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档