木野狐 (Neil Chen)

SubSonic 的字段名未转义问题修正

SubSonic 是集代码生成 / Build Provider (asp.net 2.0 的新特性) 于一身的一个非常不错的数据访问框架。其灵感来自 ROR 里的 ActionPack. 非常适合于小型网站的快速开发。
昨天我开始使用这个框架,发现了一个小问题。

我有一个字段名为 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;
        }

我增加的部分在上面代码中标注为绿色。
很奇怪,作者对表名加了方括弧,却没有加给列名,这样显然就不严谨了。

这个库中还有 MySqlDataProvider 等类也有此问题。因为我现在暂时不用 MySQL, 就先不去改那些了。

另外有一个体会就是使用开源的第三方类库时,尽量都用源代码方式加入到项目中来。否则出错了调试不进去。
现在,我使用这个框架的方法是利用它的生成类的那个网页 GenerateAllClasses.aspx 做代码生成,然后自己引用进来。虽然比默认的直接生成后在内存中编译运行要麻烦一点,但是这样便于 Debug. 还是很值得的。

posted on 2007-01-22 00:28 木野狐(Neil Chen) 阅读(2573) 评论(11)  编辑 收藏 所属分类: .NET

评论

#1楼 2007-01-22 00:47 TerryLee      

SubSonic还不错,号称是零代码数据访问层:)   回复  引用  查看    

#2楼[楼主] 2007-01-22 00:49 木野狐      

@TerryLee
呵呵,是的。不过我不敢用它的自动方式,毕竟感觉自己的控制少。理由就像这篇 post 所描述的一样。
  回复  引用  查看    

#3楼 2007-01-22 00:53 TerryLee      

@木野狐
嗯,没错

我只用它写过一个小Demo:)
  回复  引用  查看    

#4楼[楼主] 2007-01-22 01:02 木野狐      

另外使用时感觉这个东西的文档还是少。举的例子也很简单。稍微有用一点的用法都靠我自己的摸索。
比如这个:
要根据条件加载一个对象,文档(pdf)中提到可以用

对象.Load(...) 来加载,其中的参数可以是 IDataReader, DataRow, DataTable.

我用一个 IDataReader 传进去,结果搞了半天都是出错。最后调试到框架源代码里发现必须在传递 IDataReader 进去之前,自己 Read 一次才能成功。比如我写的这段简单例子里用到:

/// <summary>
/// 得到经办人所在科室的负责人
/// </summary>
/// <param name="staff"></param>
/// <returns></returns>
public static Staff GetManager(Staff staff) {
SubSonic.Query qry = new SubSonic.Query(Staff.Schema.Name);
qry.AddWhere(Staff.Columns.IsFunctionary, true);
qry.AddWhere(Staff.Columns.OfficeId, staff.OfficeId);

Staff manager = new Staff();
IDataReader reader = qry.ExecuteReader();
if (reader.Read())
{
manager.Load(reader);
}
return manager;
}

  回复  引用  查看    

#5楼 2007-01-22 11:26 ZergTant      

自动的好像有问题,只能在website上用
applacation好像不行,不知道你测试了没
我现在也不敢用它的自动方式
  回复  引用  查看    

#6楼[楼主] 2007-01-23 23:12 木野狐      

@ZergTant
恩,我还没有试过 Application Project 下用这个。不过,你说的情况应该是很有可能的,因为这个东西依赖于 Build 的时候生成一些类然后就在内存中了,但 Web Application Project 模式下 Build 和浏览的时候是独立的。

总之现在感觉还是自己生成了后搭配代码使用比较放心:)
  回复  引用  查看    

#7楼 2007-03-20 13:14 Nicol[未注册用户]

用过SubSonic的分页功能吗?数据库是sql server2000,是不是不支持?要sql server2005?   回复  引用    

#8楼 2008-03-03 17:07 Vincent Love      

SubSonic 源代码有下载,能给个地址吗?还有相关介绍
THX
  回复  引用  查看    

#9楼[楼主] 2008-03-03 17:43 木野狐(Neil Chen)      

@Vincent Love

www.codeplex.com/subsonic
  回复  引用  查看    

#10楼 2008-07-23 12:50 五味果      

subsonic做中小型项目很适合,数据访问层基本上不用再花什么精力,感觉用起来比linq to sql还要简单!

subsonic 交流qq群:subsonic群号:15019440 欢迎加入!

  回复  引用  查看    

#11楼 2009-01-02 16:24 BAsil      

很不错,学习了   回复  引用  查看    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 626405




相关文章:

相关链接: