0

我的业务层中有这样的方法。如何使这些方法参数化?

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

我在三个独立的类中有这些方法。我想知道的是如何改变这些方法来使用参数化查询,因为我在这里使用字符串连接而不改变图层体系结构。我怎么能做到这一点?

+1

永远不要用'throw ex;'重新抛出一个异常,而只需调用'throw;'来释放它。否则,您将丢失重新扔掉之前出现的堆栈跟踪。 – juharr 2014-10-16 17:47:16

+2

只要你只传递一个字符串,你就卡住了。就我个人而言,我会摆脱那种通用和易受攻击的方法executeNonQueries。如果需要保留它,我会创建一个重载,它接收一个可以在执行之前添加到命令中的通用参数列表。总的来说,最大的问题是你的图层没有任何接近正确分离的地方。你仍然在业务层做sql。你的Party对象应该有一个Save方法,而不是传递一个Party对象。 save方法应该调用数据层中的保存逻辑。 – 2014-10-16 17:50:57

+1

你可能想看看使用Dapper。它优雅地处理来自实体对象的参数映射,并摆脱您在'executeNonQuery'方法中使用的锅炉板ADO.Net代码。 – juharr 2014-10-16 17:51:21

回答

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 
} 
+0

可以通过字典字符串来保存属性类型,如字节数组byte []。 ? – chathwind 2014-10-16 17:52:51

+0

是的,'Dictionary '。 – 2014-10-16 17:53:11

+0

@ EricJ我有点困惑。我如何传递业务层中的参数?以及如何使用该字典在DataAccess图层中接收该图像。 – chathwind 2014-10-16 17:59:50