昨天我开始使用这个框架,发现了一个小问题。
我有一个字段名为 Key,在生成一个 Select 语句的查询时 sql 报错。因为 Key 是一个关键字,而 SubSonic 产生的 SQL 中对此未作转义处理。
Debug 时可以获取其产生的 SQL 如下:
SELECT TOP 100 PERCENT [cfg_Tips].[Id], [cfg_Tips].[Key], [cfg_Tips].[Descr], [cfg_Tips].[Value], [cfg_Tips].[Labels] FROM [cfg_Tips] WHERE [cfg_Tips].Key = @Key ORDER BY [Id];
我修改了一下源代码中的 SqlDataProvider.cs 里的 BuildWhere 方法,暂时解决这个问题。
protected static string BuildWhere(Query qry)
{
string where = "";
string whereOperator = " WHERE ";
foreach (Where wWhere in qry.wheres)
{
if (wWhere.ParameterValue != DBNull.Value)
{
where += whereOperator + "[" + wWhere.TableName + "].[" + wWhere.ColumnName + "] " +
Where.GetComparisonOperator(wWhere.Comparison) + " @" + wWhere.ParameterName;
}
else
{
where += whereOperator + "[" + wWhere.TableName + "].[" + wWhere.ColumnName + "] " + Comparison.Is +
" NULL";
}
whereOperator = " AND ";
}
foreach (BetweenAnd between in qry.betweens)
{
where += whereOperator + "[" + between.TableName + "].[" + between.ColumnName + "] BETWEEN @start" +
between.ColumnName + " AND @end" + between.ColumnName;
whereOperator = " AND ";
}
for (int i = qry.wheres.Count - 1; i >= 0; i--)
{
if (qry.wheres[i].ParameterValue == DBNull.Value)
{
qry.wheres.RemoveAt(i);
}
}
return where;
}
{
string where = "";
string whereOperator = " WHERE ";
foreach (Where wWhere in qry.wheres)
{
if (wWhere.ParameterValue != DBNull.Value)
{
where += whereOperator + "[" + wWhere.TableName + "].[" + wWhere.ColumnName + "] " +
Where.GetComparisonOperator(wWhere.Comparison) + " @" + wWhere.ParameterName;
}
else
{
where += whereOperator + "[" + wWhere.TableName + "].[" + wWhere.ColumnName + "] " + Comparison.Is +
" NULL";
}
whereOperator = " AND ";
}
foreach (BetweenAnd between in qry.betweens)
{
where += whereOperator + "[" + between.TableName + "].[" + between.ColumnName + "] BETWEEN @start" +
between.ColumnName + " AND @end" + between.ColumnName;
whereOperator = " AND ";
}
for (int i = qry.wheres.Count - 1; i >= 0; i--)
{
if (qry.wheres[i].ParameterValue == DBNull.Value)
{
qry.wheres.RemoveAt(i);
}
}
return where;
}
我增加的部分在上面代码中标注为绿色。
很奇怪,作者对表名加了方括弧,却没有加给列名,这样显然就不严谨了。
这个库中还有 MySqlDataProvider 等类也有此问题。因为我现在暂时不用 MySQL, 就先不去改那些了。
另外有一个体会就是使用开源的第三方类库时,尽量都用源代码方式加入到项目中来。否则出错了调试不进去。
现在,我使用这个框架的方法是利用它的生成类的那个网页 GenerateAllClasses.aspx 做代码生成,然后自己引用进来。虽然比默认的直接生成后在内存中编译运行要麻烦一点,但是这样便于 Debug. 还是很值得的。