Spiga

MySoft组件问题反馈与疑难解答

2010-03-02 10:18 by MySoft, 1187 visits, 收藏, 编辑

MySoft从2010年3月1号开始会将所有组件陆陆续续开源发布,发布开始版本(v2.7.2),期间如有使用的朋友碰到任何的问题与疑问

可及时在此反馈,我会及时解答大家的问题,并在很短的时间内修复用户碰到所有bug.

 

祝大家新的一年:身体健康、工作顺利

QQ:121849018

MSN:maoyong181@hotmail.com

Gmail:mysoft181@gmail.com

 

 

QQ讨论群(MySoft):27071789

Add your comment

36 条回复

  1. #1楼 活雷锋      2010-03-02 10:40
    强烈支持~
     回复 引用 查看   
  2. #2楼[楼主] MySoft      2010-03-05 17:08
    uxspy(13970711) 16:55:26
    lib里公布的实体生成工具有点小bug,当表名是关键字时报错
    uxspy(13970711) 16:55:59
    数据列的没事,麻烦有空修复下这个小bug吧,谢谢了
     回复 引用 查看   
  3. #3楼[楼主] MySoft      2010-03-05 17:16
    当表名与C#关键字一致会出错的情况是正常的。我不好检测表名是否为关键字,就算检测到了也不知道该如何处理。
    这种情况下最好改一下表名。以免带来不必要的麻烦!还有一种方式是不要直接生成实体类,先生成接口,然后将接口的名称改一下,上面加上Mapping来映射表名!
     回复 引用 查看   
  4. #4楼 uxspy      2010-03-07 00:01
    hi,老毛,那天在Q上给你留言了,是sqlserver2005的关键字,不是c#的,所以能否也像数据列那样加上[]就可以解决呢?谢谢!
     回复 引用 查看   
  5. #5楼[楼主] MySoft      2010-03-07 12:06
    @uxspy
    不知道你说的加上[]是什么意思,组件内部是会根据不同的数据库加上不同的限定符的,生成工具那里不会直接将限定符加上去。加限定符包括列名和表名,如:sqlserver为[fieldname],oracle为"FIELDNAME",mysql为`fieldname`,注意:oracle用限定符时必须名称为大写!
     回复 引用 查看   
  6. #6楼 uxspy      2010-03-07 20:46
    例如,我的表名是plan('plan'在sqlserver2005里是关键字),那程序里能否以[plan]代替呢?
     回复 引用 查看   
  7. #7楼[楼主] MySoft      2010-03-07 23:03
    @uxspy
    这当然是没问题的。组件内部全部都会用限定符处理!比如还有一种情况,表名为Order Details,如果不加限定符,那肯定是会出错的,所以你不用担心这个,其实实现限制符处理是最基本的要求了!如果在使用中有问题或错误,请及时反馈,
    我一直不知道你是使用时出错还是自认为会有这种问题的存,请放心使用好了,我大型项目中都在使用,如果有问题,我会第一时间修复的!
     回复 引用 查看   
  8. #8楼 uxspy      2010-03-08 14:38
    引用MySoft:
    @uxspy
    这当然是没问题的。组件内部全部都会用限定符处理!比如还有一种情况,表名为Order Details,如果不加限定符,那肯定是会出错的,所以你不用担心这个,其实实现限制符处理是最基本的要求了!如果在使用中有问题或错误,请及时反馈,
    我一直不知道你是使用时出错还是自认为会有这种问题的存,请放心使用好了,我大型项目中都在使用,如果有问题,我会第一时间修复的!



    是我使用的时候出错的,如果我描述的有问题的话,你可以在sqlserver2005中建一个数据表,表名是plan,这样当你在用实体生成工具的时候,会报错,提示你sql语句在plan附近有语法错误,因此我觉得是不是实体生成工具在执行sql语句(例如查询表名)的时候,没有把关键字比如plan加上[]限定呢?
     回复 引用 查看   
  9. #9楼 uxspy      2010-03-08 14:40
    另外提一个建议,能否把生成的借口类名加上I前缀呢?例如interface Category -> interface ICategory呢?

    否则,若接口的名称空间和最终实体的名称空间一致的情况下,会有问题的

    谢谢!
     回复 引用 查看   
  10. #10楼[楼主] MySoft      2010-03-08 14:57
    @uxspy
    我终于明白你说的问题了,生成工具查询表时直接使用的sql语句,所以没有做限定符的处理,谢谢你多次报告此错误,我会尽快修复!
     回复 引用 查看   
  11. #11楼[楼主] MySoft      2010-03-08 14:59
    @uxspy
    接口项目只是用于生成实体用,最终并不需要引用到开发项目中,用不带I的名字做为接口,只是为了生成实体时跟接口名称一致,不过我生成的接口文件前面会加上I来生成对应的接口文件。
     回复 引用 查看   
  12. #12楼 专注.net技术开发      2010-03-08 21:38
    取最大值的时候,报错:语法错误 (操作符丢失) 在查询表达式 'max([Classification].[ClassIndex]) [ClassIndex]' 中。
    代码如下:int maxindex = DbSession.Default.Max<Classification, int>(Classification._.ClassIndex, WhereClip.All);
     回复 引用 查看   
  13. #13楼 uxspy      2010-03-09 17:57
    引用MySoft:
    @uxspy
    接口项目只是用于生成实体用,最终并不需要引用到开发项目中,用不带I的名字做为接口,只是为了生成实体时跟接口名称一致,不过我生成的接口文件前面会加上I来生成对应的接口文件。



    了解了,谢谢
     回复 引用 查看   
  14. #14楼 kumaws      2010-03-10 15:46
    你好老毛今天刚用到你的Data组件,还不太熟悉。你的QueryCreator返回的ToTable()是ISourceTable的,我怎么用才返回datatable??
     回复 引用 查看   
  15. #15楼[楼主] MySoft      2010-03-11 09:36
    @kumaws
    你好,返回内部实现的ISourceTable是为了扩展更多的功能,内部的SourceTable是继承自DataTable与ISourceTable,所以ISourceTable可以直接转换为DataTable
    你想返回DataTable只要这样写就可以了。
    .ToTable() as DataTable;
     回复 引用 查看   
  16. #16楼[楼主] MySoft      2010-03-11 09:38
    @专注.net技术开发
    你好,这个问题已经解决,由于Access里的语法有些并不符合SQL92规范,所以导致有些写法按照通用的语法去写就会出错!我已经单独为Access写了一些实现!我会尽早发布稳定的版本!
     回复 引用 查看   
  17. #17楼 view      2010-03-13 11:08
    强烈支持,期待您的发布
     回复 引用 查看   
  18. #18楼 ﹏執著*      2010-03-25 23:02
    等待新版本的出现 强烈支持毛哥
     回复 引用 查看   
  19. #19楼 CFan.Net      2010-03-27 15:47
    请教一问题:
    QueryCreator QC = QueryCreator.NewCreator()
    .From("Products")
    .AddField("ProductName")
    .AddField("CategoryName")
    .AddWhere(Products._.CategoryID==1 || Products._.CategoryID==2)
    .Join(JoinType.LeftJoin, "Categories", "Products.CategoryID=Categories.CategoryID");
    中的AddWhere如果用字符串写就出问题了。如“AddWhere("CategoryID=1")”,就会提示“Category”不明确列,如果写成“AddWhere("Products.CategoryID=1")”则生成的sql语句就就成"[Products.CategoryID]=1”了。


    再者,这里的AddWhere如果有多个,默认的是"and"关系吧,那如何设置成“or”的关系呢?
     回复 引用 查看   
  20. #20楼[楼主] MySoft      2010-03-28 00:05
    你好,添加条件最好使用AddWhere(fieldname,value)或AddWhere(tablename,fieldname,value)你写成AddWhere("Products.CategoryID=1")应该也不会错的。如果多表关联,肯定就不能直接用AddWhere("CategoryID=1")了,这样会导致CategoryID不知道是属于哪个列的。我示例中只能做为参考。
    QueryCreator如果要使用Or,可以用AddWhere(where)来添加!
     回复 引用 查看   
  21. #21楼 CFan.Net      2010-03-28 17:02
    是这样的,因为需求是不能用强类型查询,只能用字符往AddWhere里边传了。 所以才想请教有没有办法的。

    另外,在NBearLite中有一个ToCommandText方法蛮好用的,可以在调试时直接输出sql语句,比如 db.From<Product>().Where(Product._.ID=1 && Product._.Name.like("%a"), 在调试的过程中就可以用db.From<Product>().Where(Product._.ID=1 && Product._.Name.like("%a").ToCommandText()方法在即时窗口中输出sql语句,非常有用,建议新版中添加此功能,,呵呵。
     回复 引用 查看   
  22. #22楼[楼主] MySoft      2010-03-29 09:47
    @CFan.Net
    因为where条件会有复杂的情况,只是处理and与or是不够的,还有可能是条件组合时的优先级,子查询等。

    增加sql输出可以考虑加上,请等待正式版!
     回复 引用 查看   
  23. #23楼 永远的阿哲      2010-04-04 17:51
    我现在用的Access数据库,提几个建议吧
    1.考虑到代码规范,生成的代码能否首字母大字
    2.生成工具如果一次只勾选一个表或二个表,代码可以生成出来,如果全选,则报异常
    3.生成的代码编码有问题,在vs2005中打开汉字乱码,我用notepad2打开后把编码从utf8改成utf8包含签名,就好了
    4.access如果取别名则报错,原因是access必需使用as关键字,而生成的sql脚本没有。
    5.我的理解是:insert方法是一次插入部分字段,save方法是将实体以整体的方式插入。请问现在是做成了两个方法,为什么不在insert中做成重载。
    6.Update方法为什么不能以实体的方式更新,而只能按字段更新,我现在如果是以实体的方式更新,用的是InsertOrUpdate,不知是否恰当。
    7.在涉及到字段与值的方面,一般是用Field[]与object[],可否考虑做成Dictionary<>,这样感觉优雅很多
    8.在教程方面能否尽快补完,这点Hxj.Data就做的很好,我几乎是通过看他的教程来学习了你的组件。

    我的操作环境是2K3+vs2005+.net3.5sp1,以上说的问题在我的环境中已反复测试多次,不保证在别的环境也出现同样的问题。
     回复 引用 查看   
  24. #24楼 永远的阿哲      2010-04-04 21:33
    通过toTable强转出的DataTable无法Clone,不知注意了没?
     回复 引用 查看   
  25. #25楼[楼主] MySoft      2010-04-06 08:49
    @永远的阿哲
    你好,不知道你说的无法Clone是什么意思,是出错还是克隆不正确,在DataTable中的Clone()方法只克隆结构,要用Copy()方法才是克隆数据。我组件中的ISourceTable.Clone()则与DataTable.Copy()相同!
     回复 引用 查看   
  26. #26楼[楼主] MySoft      2010-04-06 09:49
    @永远的阿哲
    首先,感谢你使用MySoft并提出这么多宝贵意见。下面就你提出的问题进行一下解答:
    注:请下载最新的版本再试
    1.在生成工具上有相应的选项,可以对表或字段首字母(全部)大写处理
    2.选择二个表与选择多个表的逻辑处理是一样的,应该不会有问题。
    3.你生成类文件后,请在vs.net2005中将【自动检测不带签名的utf-8编码】选中就不会出现乱码的问题了
    4.Access中as引起的bug已经在新版本中得到修复
    5.Save(entity)有两种用途,保存与更新,用于对实体的操作
    entity上有Attach()与Detach()方法用于处理实体状态
    entity.Attach(fields)与entity.Detach(fields)里面可以带参数,表示插入或更新时移除某些列
    6.Update与Insert是用于特殊需求时使用。一般不用于操作实体。
    Update一般用于批量更新
    7.一般情况下不需要使用Insert来操作,Field[]+Object[]的方式其实也是比较方便的,如有需要,可以自己对DbSession进行扩展。
    8.文档方面确实比较欠缺,近段时间比较忙,很抱歉!
     回复 引用 查看   
  27. #27楼 永远的阿哲      2010-04-06 12:53
    哈哈,还真是奇了怪了,今天早上来一试,有几个问题居然自动好了~~
    1.生成代码的大小写,怪我没看仔细,哈哈
    2.生成代码报异常的问题,只能说是不稳定,时好时坏(报异常),还可以用。
    3.那个字符编码,LZ真是牛人啊
    4.对于Access的别名,确实是有问题:我是这样写的:
    DataTable dt = session.From<News>().Select(News._.ID.As("id")).ToTable() as DataTable;
    异常为:语法错误 (操作符丢失) 在查询表达式 '[News].[ID] [id]' 中。
    可以看到确实没有加As
    5.Insert,Update,Save之间的关系我大概是理解了。一般如果是对实体进行整体操作,用Save,如果将实体置为Detach(),则是插入状态,Attach(),则是更新状态,默认是Detach()插入状态。如果是只需要对表进行部分更新,两种方式:使用实体并通过Attach()排除不需要更新的字段;使用Update。如果只对表部分字段进行插入,用实体并设置Detach(),或者使用Insert进行部分插入。在批量插入或更新方面Insert/Update有优势,因为不需要重复构建实体,直接操作字段。
    6.其实我还是觉得使用Directory<Field, Object>比Field[]+Object[]好用,且这不仅仅是好用,使用前者在数据结构就将键与值一一对应了,而后者还需要用眼睛去检查,对应错了也很难去检查。我自己还是不扩展了吧,一来没那个能力,二来如果您这边又更新了,那我是不是在新版本上再修改一次呢?而这也不用花很多精力去改,因为在内部调动上仍然可以是Directory<>的重载调用Field[]+Object[]的重载。
    7.Clone问题居然神了,昨天DataTable dt = session.From<News>().ToTable() as DataTable;DataTable newDt = dt.Clone;后面一句还报异常:...未实现默认的构造函数。今天居然又通过了。哎~~~
    8.再提个建议,生成器生成的代码,数据库如果是值类型,生成的字段则是可空类别:Nullable<T>,比如是数字,生成的则是Int32?.但是在注释上显示的是:数据类别:Nullable~1,我想是因为是泛型,所以GetType()后的ToString()就显示了这个了,应该取其Name属性(没有看源代码,我猜的)。
     回复 引用 查看   
  28. #28楼 永远的阿哲      2010-04-06 13:21
    再问两个问题:
    1.每次连接数据库我都会重新实例化Session,请问这对性能有没有影响。
    2.我的代码结构是这样的:
    DB类:
        class DB
        {
            DbSession session = new DbSession("ConnectionString");
    
            public DB()
            {
                session.RegisterSqlLogger(LogSql);  
            }
    
            private static void LogSql(string sql)
            {
                using (FileStream fs = new FileStream(@"c:\sql.sql", FileMode.Append))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine(sql);
                    }
                }
            }
    
            public DataTable DoWork()
            {
                return session.From<News>().ToTable() as DataTable;
            }
    
        }
    


    WinForm展示:
    private void button1_Click(object sender, EventArgs e)
            {
                DataTable dt = new DB().DoWork();
                gvData.DataSource = dt;
            }
    


    但是在使用中却发现写入的sql语句有重复。
    我想,是不是在session实例化的时候使用了连接池技术还是单例模式,这样每次生成相同接字符串的session实际上是没有new的,但是这样它的Session.RegisterSqlLogger委托链就记录了所有注册过的Handler了。
    我找这个问题找了很长时间,一开始还以为是组件有问题,一次性生成的sql有几十K之多,吓我一跳~~~
    我现在的做法是建个委托Handler,指向DoWork,然后在构造函数里先UnRegisterSqlLogger(Handler),再RegisterSqlLogger(Handler),但是感觉这样写的好丑。请问有什么更好的方法?

    还有几个问题,午睡起来了再说~~~
     回复 引用 查看   
  29. #29楼[楼主] MySoft      2010-04-06 15:35
    @永远的阿哲
    你好,只需要将DbSession设置为静态的即可。DbSession内部是有缓存的,创建相同的配置返回相同的对象。当DbSession(connectName)中的connectName不相同时,则会生成另一个会话对象。

    static readonly DbSession session;

    static DB()
    {
    session = new DbSession("ConnectionString");
    session.RegisterSqlLogger(LogSql);
    }

    注册事件最简洁的方法如下:
    session.RegisterSqlLogger(log => File.AppendAllText("c:\\log.txt", log + "\n"));
     回复 引用 查看   
  30. #30楼 永远的阿哲      2010-04-15 17:00
    我再来问一个问题:
    如果sqlserver里存在架构,那是不是生成代码的工具就不能用了,这个ORM也不能用了~~
     回复 引用 查看   
  31. #31楼 永远的阿哲      2010-04-15 17:34
    我想了个丑方法,

    比如是SysFeedBack.FeedBackType表
    先建个没有架构的表:FeedBackType,用工具把代码生成出来,然后在生成代码的GetTable()处把表名从FeedBackType改成SysFeedBack].[FeedBackType
    哈哈!
    初步测了下,新增与查询可以通过
    希望在下一版中能解决此问题
     回复 引用 查看   
  32. #32楼 永远的阿哲      2010-04-20 15:37
    再来提一个,在sqlite访问中批量操作好象不行吧,以下是我的代码:
    using (DbTrans trans = session.BeginTrans())
                {
                    try
                    {
                        DbBatch batch = trans.BeginBatch();
                        //删除本节点
                        CollectType del = GetOneType(delId);
                        del.IsDel = 1;
                        del.Attach();
                        batch.Save<CollectType>(del);
                        //移动子节点
                        foreach (CollectType ct in GetChildType(delId))
                        {
                            ct.Pid = newId;
                            ct.Attach();
                            batch.Save<CollectType>(ct);
                        }
                        batch.Process();
                        trans.Commit();
                        return true;
                    }
                    catch
                    {
                        trans.Rollback();
                        return false;
                    }
                    finally
                    {
                        trans.Close();
                    }
                }
    

    从生成的sql文件看,sql语句是生成成功了,但最终执行的效果是只更新了一两条数据.不知您注意了没有
     回复 引用 查看   
  33. #33楼 安布雷拉      2010-04-27 16:38
    hi maoyong:
    我在使用MySoft.Data组件做Demo时候,使用UpdateCreator 更新实体时候出现错误。错误提示是:“请设置需要更新的字段列表”

    我的更新方式是采用实体来更新,下面贴出代码。

                    MyTable mytable = new MyTable()
                    {
                        PrimaryCode = 1,
                        SomeInt = 1002,
                        SomeDateTime = DateTime.Now,
                        SomeVarchar = "MoveUpdate4"
                    };
    
                    UpdateCreator uc = UpdateCreator.NewCreator()
                        .From<MyTable>()
                        .SetEntity<MyTable>(mytable, true);
    
                    DbSession.Default.Excute(uc);
    
     回复 引用 查看   
  34. #34楼[楼主] MySoft      2010-04-27 20:35
    @安布雷拉
    你好,请问一下你是否将OnPropertyValueChange()方法去掉了!如果实体只是用于读取数据,则可以去掉,否则这个方法是必须的!
     回复 引用 查看   
  35. #35楼 安布雷拉      2010-04-28 10:34
    To MySoft:
    仔细看过了OnPropertyValueChange()确实存在于DataEntity里的,为了验证我又用"数据库实体生成工具"重新生成了一次数据实体。可以错误提示仍然一样。我是这样理解的:在调用UpdateCreator更新实体时候,应该会去自动判断实体的PrimaryKey属性。然后生成相应的SQL语句:比如Where PrimaryCode = 1 。但是调试抛出的错误,有点莫不着头脑了。
     回复 引用 查看   
  36. #36楼 新人jin      2010-07-28 16:59
    请问DropDownList绑定DbSession查询的值的语句怎么写?
     回复 引用 查看