SubSonic是一个不错的轻量级.net ORM开源框架,非常适合进行网站以及小型B/S应用程序开发,但还有一些小地方不是很完善,不过作者很勤奋,前几天发布了最新的2.1版。
  最近用它开发了一个小应用程序,在一个数据库查询中要求两个in操作,但发现SubSonci不支持多个in,使用多个in后,只有最后一个in会生效。阅读他的代码发现,他只保存了最后一个in的列名和对应的值到inColumnName和inList数组中。看来要想使用多个
in必须要修改他的数据结构,于是我把保存in的变量修改为hashtable类型,key保存字段名,value保存对应的值,让后对相应的调用进行一番修改,搞定!
 
主要修改了以下几个地方:

1.保存in的数据结构,在Query.cs的612行
       
internal object[] inList;
internal string inColumn = string.Empty;
            ||
            \/
修改为hashtable
internal Hashtable inList = new Hashtable();

2.3个in方法的重载,在Query的762行
        public Query IN(string columnName, object[] listItems)
        {
            //inColumn = columnName;
            //inList = listItems;
            // modify by chao @ 2008-8-18
            inList.Add(columnName, listItems);
            return this;
        }
其它两个类似。
3.附加参数值的方法AddWhereParameters,在DataProvider.cs的539行
                //if(qry.inList.Length > 0)
                //{
                //    int inCount = 1;
                //    foreach(object inItem in qry.inList)
                //    {
                //        cmd.AddParameter("in" + inCount, inItem);
                //        inCount++;
                //    }
                //}
 
                  ||
                  \/
 
                if (qry.inList.Count > 0)
                {
                    int inCount = 1;
                    foreach (DictionaryEntry de in qry.inList)
                    {
                        object[] inList = (object[])de.Value;
                        if (inList.Length > 0)
                        {
                            foreach (object inItem in inList)
                            {
                                cmd.AddParameter("in" + inCount, inItem);
                                inCount++;
                            }
                        }
                    }
                }

4.添加参数的BuildWhere方法,在DataProvider.cs的783行
                //if(qry.inList.Length > 0)
                //{
                //    if(isFirstPass)
                //    {
                //        where += whereOperator;
                //    }
                //    else
                //    {
                //        where += SqlFragment.AND;
                //    }
                //    where += qry.Provider.DelimitDbName(qry.inColumn) + SqlFragment.IN + "(";
                //    bool isFirst = true;
                //    for(int i = 1; i <= qry.inList.Length; i++)
                //    {
                //        if(!isFirst)
                //        {
                //            where += ", ";
                //        }
                //        isFirst = false;
                //        where += Utility.PrefixParameter("in" + i, qry.Provider);
                //    }
                //    where += ")";
                //}
 
                  ||
                  \/
                 
                if (qry.inList.Count > 0)
                {
                    int inCount = 1;
                    foreach (DictionaryEntry de in qry.inList)
                    {
                        if (isFirstPass)
                        {
                            where += whereOperator;
                            isFirstPass = false;
                        }
                        else
                        {
                            where += SqlFragment.AND;
                        }
                        where += qry.Provider.DelimitDbName(de.Key.ToString()) + SqlFragment.IN + "(";
                        bool isFirst = true;
                        string[] inList = (string[])de.Value;
                        foreach (object inItem in inList)
                        {
                            if (!isFirst)
                            {
                                where += ", ";
                            }
                            isFirst = false;
                            where += Utility.PrefixParameter("in" + inCount, qry.Provider);
                            inCount++;
                        }
                        where += ")";
                    }
                }

  说明,以上的修改是基于SubSonic的2.0.3版源码的。附件中是我修改的问见,可以下载后直接替换掉原文件编译就可以。如果想省事,直接用我编译过的dll也是可以的。