我有一个非静态类,其中包括14个可公开访问的属性。该类还将具有三种使用类实例中的值返回Update,Insert和Delete MySQL查询(作为字符串)的方法。一些属性可以为空,因此我需要在创建MySQL查询之前进行检查。
此刻,我将按照以下方式进行操作:
public string GetNewString()
{
StringBuilder sb = new StringBuilder("INSERT INTO `dbname`.`tablename` (`OrderID`, `Code`, `Supplier`, `Unit`, `From`, `To`, `StockType`, `ItemsOrdered`, `QtyNewItems`, `PerNewItems`, `ArrivedDate`, `CompletedDate`, `Notes`, `OrderDate`) VALUES (");
//PK & not nullable, so no check
sb.Append($"'{this.OrderID}', ");
if (this.Code.ToString().Length.Equals(0))
{
sb.Append("NULL, ");
}
else
{
sb.Append($"'{this.Code}', ");
}
if (this.Supplier.ToString().Length.Equals(0))
{
sb.Append("NULL, ");
}
else
{
sb.Append($"'{this.Supplier}', ");
}
我的问题是,对于每个属性,如果没有If / Else循环,是否还有一种更简单的方法?我尝试使用三元运算符,但它却不太像。除了肿该方法之外,我现在的操作方式没有任何错误(至少从我的观察中可以看出)。
此外,我不是C#方面最优秀或经验最丰富的人,所以对新手问题感到抱歉!
答案 0 :(得分:1)
参数化查询可帮助您避免SQL注入,但您不仅仅将其用于此目的。它们可以帮助您编写更好的代码(不丢失引号或将值中的现有引号加倍,不存在小数和双精度的解析问题)和更具可读性的代码。
请注意,如果要插入空值,请使用DBNull.Value。
string query = @"INSERT INTO `dbname`.`tablename`
(`OrderID`, `Code`, `Supplier`, `Unit`, `From`, `To`,
`StockType`, `ItemsOrdered`, `QtyNewItems`, `PerNewItems`,
`ArrivedDate`, `CompletedDate`, `Notes`, `OrderDate`)
VALUES
(@OrderID, @Code, @Supplier, @Unit, @From, @To,
@StockType, @ItemsOrdered, @QtyNewItems, @PerNewItems,
@ArrivedDate, @CompletedDate, @Notes, @OrderDate)";
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.Add("@OrderID", MySqlDbType.Int32).Value = orderID;
cmd.Parameters.Add("@Code", MySqlDbType.VarChar).Value = (string.IsNullOrEmpty(Code) ? DBNull.Value : (object)code) ;
---- and so on for all other parameters, no need to convert them to strings -----
但是,如果您的主要关注点是代码的简单性(IE越少越好),那么您可能应该看一下隐藏了ADO.NET所有样板代码的某种ORM。例如,使用免费的ORM Dapper(轻量级ORM库),您可以简单地编写此代码
MyOrderClass orderInstance = this;
using(IDbConnection cnn = GetYourOpenConnectionFromThisMethod())
{
string query = " --- as above --- ";
int result = cnn.Execute(query, orderInstance);
}
这里唯一需要注意的是,您的MyOrderClass属性应该与数据库字段具有相同的名称。