【问题标题】:How to make these methods parameterized?如何使这些方法参数化?
【发布时间】:2014-12-12 04:32:39
【问题描述】:

我的业务层中有这样的方法。

    public Boolean saveParty(Party ptObj)
    {
        string query1 = "EXEC insertToParty'" + ptObj.PTRegID + "','" + ptObj.PTName.Replace("'", "''") + "','" + ptObj.PTSymARR + "','" + ptObj.PTSymName + "','" + ptObj.elecRepCol + "','" + ptObj.PTSec + "','" + ptObj.phPri + "','" + ptObj.phSec + "','" + ptObj.bsAddress + "','" + ptObj.secAddress + "','" + ptObj.addedUser + "','" + ptObj.addedDate + "','" + ptObj.PTstatus + "'";
        return (new DataAccessLayer().executeNonQueries(query1));
    }

在我的数据访问层中,我创建了执行这样的非查询。

public Boolean executeNonQueries(string query02)
    {
        Boolean flag = false;
        SqlConnection con = null;
        SqlCommand com = null;
        try
        {
            con = new SqlConnection(DBConnect.makeConnection());
            con.Open();
            com = new SqlCommand(query02, con);
            com.ExecuteNonQuery();
            flag = true;
        }
        catch (Exception ex)
        {
            flag = false;
            throw ex;
        }
        finally
        {
            com.Dispose();
            con.Close();
        }
        return flag;
    }

在我的数据库连接层中,我已经这样实现了。

     public static string makeConnection()
    {
        string con = ConfigurationManager.ConnectionStrings["MYDB.Properties.Settings.ConString"].ToString();
        return con;
    }

我在三个不同的类中有这些方法。我想知道的是如何更改这些方法以使用参数化查询,因为我在这里使用字符串连接而不更改层架构。我怎样才能做到这一点?

【问题讨论】:

  • 永远不要用throw ex; 重新抛出异常,而是通过调用throw; 来“释放它”。否则,您会丢失重新抛出之前的堆栈跟踪。
  • 只要你只传递一个字符串,你就会被卡住。就我个人而言,我会摆脱那种通用且易受攻击的方法 executeNonQueries。如果您需要保留它,我将创建一个重载,该重载接收可以在执行命令之前添加到命令的通用参数列表。一般来说,这里最大的问题是您的图层没有接近适当的分离水平。你还在业务层做sql。您的 Party 对象应该有一个 Save 方法,而不是传递一个 Party 对象。 save 方法应该调用数据层中的保存逻辑。
  • 您可能想考虑使用 Dapper。它优雅地处理与实体对象之间的参数映射,并摆脱了 executeNonQuery 方法中的样板 ADO.Net 代码。
  • +1 表示Dapper。最近是学习新东西的最佳时间
  • @juharr 有 Dapper 的代码示例吗?

标签: c# sql-server data-access-layer parameterized-query business-layer


【解决方案1】:

您的业务层没有形成 SQL 字符串的业务。它应该关注域,并将持久性留给数据访问层。如果可能,将该职责完全移至数据访问层。

如果您的项目中的实际情况阻止您将职责放在它们所属的位置,您可以考虑让业务层传递带有参数占位符的 SQL 语句,以及包含每个参数名称和参数值的条目的字典。

在业务层

public Boolean saveParty(Party ptObj)
{
    string query1 = "EXEC insertToParty @Id, @Name, etc";

    Dictionary<string, object) p = new Dictionary<string, object>();
    p.Add("@Id", ptObj.PTReqID);
    p.Add("@Name", ptObj.PTName);
    // etc.

    return (new DataAccessLayer().executeNonQueries(query1));
}

在数据访问层,添加字典中的参数,例如

public Boolean executeNonQueries(string query02, Dictionary<string, object> parameters)
{
    // Your existing code to setup connection
    foreach (var param in dictionaryWithParametersAndValues)
    {
        com.AddWithValue(param.Key, param.Value);
    }
    com.ExecuteNonQuery(); 
    // Rest of your existing code
}

【讨论】:

  • 字典字符串可以保存像字节数组 byte[] 这样的属性类型。 ?
  • 是的,Dictionary&lt;string, object&gt;
  • @EricJ 我有点困惑。如何在业务层传递参数?以及如何使用该字典在 DataAccess 层中接收它。
  • 通过字典传递参数不一定是最好的方法......有办法解决这个问题;但是是的,它会工作
  • @MarcGravell:是的,就像 EF 或 Dapper。当前的分层不是最佳的。你对一个好的创可贴有其他想法吗,以防这就是 OP 所能做的一切?
猜你喜欢
  • 1970-01-01
  • 2014-07-20
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多