框架研究(QQ群)第一次的讨论记录(07-05-17)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 2007-05-17 17:50:47 Ivony...近期我会公布DbUtility的两个应用实例…… 2007-05-17 17:51:37 jykDbUtility 是什么来着 2007-05-17 17:52:31 Ivony...一个是怎样使用模板功能查询指定时间段内数据。

2007-05-17 17:50:47 Ivony...
近期我会公布DbUtility的两个应用实例……

2007-05-17 17:51:37 jyk
DbUtility 是什么来着

2007-05-17 17:52:31 Ivony...
一个是怎样使用模板功能查询指定时间段内数据。由于查询数据的SQL比较复杂,如果将时间段直接嵌入其中,必然让SQL变得像裹脚布,我们用DbUtility提供的SQL模板功能非常漂亮的解决了这个问题。

2007-05-17 17:52:44 Ivony...
DbUtility就是我的那个数据访问框架哈……

2007-05-17 17:53:34 jyk
??

2007-05-17 17:53:48 jyk
我觉得查询是一个比较简单的问题

2007-05-17 17:54:21 jyk
呵呵,我有一个查询控件,配置一下就可以了,都不用写代码的。

2007-05-17 17:54:53 Ivony...
二是非存储过程分页数据,我们都知道,现在最流行的分页是采用存储过程来做的,但大多数的存储过程也是采取了拼接SQL语句的方式,这使得参数化的查询无法实现,因为存储过程的参数个数是固定的,这个实例演示了如何使用DbUtility强大的模板功能在C#中安全的拼接SQL,保持参数化的查询……

2007-05-17 17:55:50 Ivony...

img_a6339ee3e57d1d52bc7d02b338e15a60.gif SELECT Days, COUNT( Days ) AS Visitors FROM 
img_a6339ee3e57d1d52bc7d02b338e15a60.gif(
img_a6339ee3e57d1d52bc7d02b338e15a60.gif    SELECT datediff( dd, Prev, ( SELECT Date FROM Sessions WHERE ID 
=  DaysCount.CurrentID ) ) AS Days
img_a6339ee3e57d1d52bc7d02b338e15a60.gif    FROM
img_a6339ee3e57d1d52bc7d02b338e15a60.gif    (
img_a6339ee3e57d1d52bc7d02b338e15a60.gif        SELECT MAX( Sessions.Date ) AS Prev, MAX( TodayVisitor.ID ) AS CurrentID
img_a6339ee3e57d1d52bc7d02b338e15a60.gif            FROM 
<! Sessions >  
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                INNER JOIN
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                (
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                    SELECT MAX( ID ) AS ID , CookieID
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                        FROM 
<! Sessions,DaysCount >                
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                        GROUP BY CookieID
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                ) AS TodayVisitor
img_a6339ee3e57d1d52bc7d02b338e15a60.gif                ON ( Sessions.CookieID 
=  TodayVisitor.CookieID )
img_a6339ee3e57d1d52bc7d02b338e15a60.gif            
img_a6339ee3e57d1d52bc7d02b338e15a60.gif            WHERE Sessions.ID 
<  TodayVisitor.ID
img_a6339ee3e57d1d52bc7d02b338e15a60.gif            GROUP BY Sessions.CookieID
img_a6339ee3e57d1d52bc7d02b338e15a60.gif     )  AS DaysCount
img_a6339ee3e57d1d52bc7d02b338e15a60.gif) AS Resault
img_a6339ee3e57d1d52bc7d02b338e15a60.gifGROUP BY Days ORDER BY Days 
img_a6339ee3e57d1d52bc7d02b338e15a60.gif


2007-05-17 17:55:55 Ivony...
像这种SQL呢?

2007-05-17 17:56:00 Ivony...
简单么?

2007-05-17 17:56:25 jyk
 INNER JOIN  可以写个视图,简化了一部分

2007-05-17 17:56:37 Ivony...
呵呵……几乎每个SQL都是这样

2007-05-17 17:56:43 Ivony...
你每个都写视图?

2007-05-17 17:56:51 jyk
我的 分页控件 本来就是使用SQL语句的,不用存储过程。

2007-05-17 17:56:57 jyk
是呀

2007-05-17 17:57:01 jyk
视图多了一点

2007-05-17 17:57:09 Ivony...
需求变更怎么办?

2007-05-17 17:57:24 Ivony...
视图那么多,你知道哪个是干什么用的?管理成本

2007-05-17 17:57:26 jyk
不过程序可读性强了不少

2007-05-17 17:57:40 jyk
当然要管理了

2007-05-17 17:57:55 jyk
有得必有失嘛

2007-05-17 17:57:55 Ivony...
这个是笑话了,如果大量的使用视图,反而会让可读性下降……

2007-05-17 17:58:00 Ivony...
这个SQL并不复杂……

2007-05-17 17:58:15 Ivony...
这是因为它只是表述查询逻辑

2007-05-17 17:58:29 Ivony...
如果加上时间段的筛选

2007-05-17 17:58:33 Ivony...
那就吓人了……

2007-05-17 17:58:50 jyk
好像是一个分页算法

2007-05-17 17:58:58 Ivony...
不是……

2007-05-17 17:59:04 jyk

2007-05-17 17:59:21 Ivony...
这是计算访问者新近度的

2007-05-17 17:59:37 Ivony...
计算某一段时间内,每一个访问者距离上一次访问所间隔的时间。

2007-05-17 18:00:36 Ivony...
所以这里几乎每一个表都要加上时间的筛选……

2007-05-17 18:00:49 Ivony...
而这个时间段又是由客户选择的……

2007-05-17 18:01:02 jyk
??

2007-05-17 18:01:03 Ivony...
所以,SQL会变得像裹脚布一样……

2007-05-17 18:01:52 Ivony...
何况,你的视图同样可以通过拼接SQL做到,而且管理成本更低……

2007-05-17 18:02:49 Ivony...
在这个SQL中,通篇看不到一个参数,它却可以按照日期进行筛选,是不是很奇怪?

2007-05-17 18:05:48 jyk
奇怪呀

2007-05-17 18:06:07 Ivony...
秘密就是这个:<!Sessions>

2007-05-17 18:06:41 Ivony...
看看相关代码:

2007-05-17 18:07:27 jyk
一直想问 <!Sessions>  是怎么意思呀

2007-05-17 18:07:46 Ivony...
这是一个模板占位符……

2007-05-17 18:08:10 Ivony...
他表示一个模板,然后我们自己写一个方法,将这个模板予以替换……

2007-05-17 18:08:12 jyk
和参数有什么不同吗

2007-05-17 18:08:51 Ivony...
      return TemplateExpression.CreateTemplateExpression( "( SELECT * FROM {0:} WHERE Date BETWEEN {2} AND {3} AND DomainID = {4} ) AS {1:}", tableName, alias, begin, end, 1 );
 

2007-05-17 18:09:26 Ivony...
这个模板被替换的代码大体如上。

2007-05-17 18:10:17 Ivony...
大体上,这个模板会被替换为:
( SELECT * FROM Sessions WHERE Date BETWEEN {2} AND {3} AND DomainID = {4} ) AS Sessins

2007-05-17 18:11:22 Ivony...
其中的{2}、{3}、{4}是参数占位符,他们会被相应的参数,如begin(起始时间)、end(结束时间)、1(网站ID)所替换。

2007-05-17 18:11:31 jyk
基本就是拼接(替换)SQL语句

2007-05-17 18:12:16 Ivony...
并且,是以参数的形式替换,也就是说,他们会在SQL中生成参数表达式@ParamX,然后以参数的形式传进去……

2007-05-17 18:13:02 Ivony...
不要小看拼接SQL语句……

2007-05-17 18:13:35 Ivony...
不论是LINQ、还是分页存储过程,乃至包括视图,哪个不是拼接SQL?

2007-05-17 18:13:44 jyk
我也用拼接SQL语句  语句呀

2007-05-17 18:13:51 jyk
我的分页控件就是拼接SQL语句 

2007-05-17 18:14:18 jyk
视图 不是拼接 

2007-05-17 18:14:28 Ivony...
呵呵……

2007-05-17 18:14:41 Ivony...
实际执行中,还是等同于SQL解析的……

2007-05-17 18:14:47 jyk
分页存储过程 也可以不拼接,只是为了所谓的通用才拼接的

2007-05-17 18:15:23 Ivony...
将参数嵌入SQL本质上就是拼接……

2007-05-17 18:15:41 Ivony...
这是DbUtility最基本的拼接……

2007-05-17 18:16:13 Ivony...
DbUtility还能玩很多高级的拼接技巧,如上面那个例子中所展现的……

2007-05-17 18:17:14 jyk
其实我们都面临一个问题:能不能把自己的想法,通俗一点的告诉给其他人。让听众很容易理解

2007-05-17 18:17:44 Ivony...
并且!很重要的是,DbUtility始终保证拼接的安全,在任何形式的拼接中,不论参数的格式是否固定,不论拼接的复杂程度,子句的多寡,DbUtility始终将任何一个输入包装成参数,保证安全……

2007-05-17 18:17:58 Ivony...
并且!很重要的是,DbUtility始终保证拼接的安全,在任何形式的拼接中,不论参数的个数是否固定,不论拼接的复杂程度,子句的多寡,DbUtility始终将任何一个输入包装成参数,保证安全……

2007-05-17 18:19:53 jyk
http://blog.csdn.net/jyk/archive/2007/03/01/1518354.aspx

2007-05-17 18:20:06 jyk
不知道这个有没有说明白

2007-05-17 18:20:18 jyk
分页控件的想法

2007-05-17 18:20:23 Ivony...
我的观点:Query,不管你在上面玩多少花样,说到底层,就是拼接SQL,分析SQL,这方面强大,你上面的应用就好玩,这个基础差,你上面的应用就都是空中楼阁。

2007-05-17 18:21:04 jyk
同意

2007-05-17 18:21:28 jyk
DbUtility 不会只是做查询吧,应该还有其他的功能吧

2007-05-17 18:21:55 Ivony...
DbUtility负责我数据访问框架的底层工作

2007-05-17 18:22:14 Ivony...
它主要工作就是拼接生成解析和执行查询。

2007-05-17 18:22:23 jyk
应该是负责SQL语句的地方吧

2007-05-17 18:23:19 Ivony...
首先它有强大的SQL拼接解析引擎CommandParser、SqlDom等组件,也有一大堆方便实用的方法来帮助组织查询结果。

2007-05-17 18:23:51 Ivony...
如ExecuteSingleRow、ExecuteData、ExecuteSingleColumn等等……

2007-05-17 18:25:15 添先盼
不知道微软出的"Enterprise Library 3.0 "有没有用?

2007-05-17 18:25:22 Ivony...
垃圾……

2007-05-17 18:25:26 添先盼
个人感觉这个已经蛮够用了。

2007-05-17 18:25:29 添先盼
呵呵

2007-05-17 18:25:29 Ivony...
还有,那不是微软出的……

2007-05-17 18:25:41 jyk
我的底层是  SQL 的处理 + Datahelp 是两部分组成的。
Datahelp 部分基本已经成熟,
SQL语句部分就很灵活了。
 

2007-05-17 18:26:08 jyk
Enterprise Library 3.0 是企业级...

2007-05-17 18:26:15 jyk
是什么来着

2007-05-17 18:26:27 添先盼
嗯,没错,但我比较反对说这个是垃圾,哈哈。

2007-05-17 18:26:39 Ivony...
我不说大话,仅仅DbUtility的基本功能,可以比使用SqlHepler减少%300的代码

2007-05-17 18:27:05 Ivony...
你说那个东西不是垃圾是啥?

2007-05-17 18:27:16 jyk
我想说 SqlHepler 是垃圾来着

2007-05-17 18:27:33 jyk
Enterprise Library 3.0 还没有看过的

2007-05-17 18:27:37 添先盼
呵呵,不争了。

2007-05-17 18:27:49 jyk
讨论嘛,没关系的

2007-05-17 18:27:54 Ivony...
实际应用中,比直接使用ADO.NET最多减少1500%以上的代码……

2007-05-17 18:28:08 Ivony...
还有,再次重申,Enterprise Library不是微软出的……

2007-05-17 18:28:13 jyk
1500% ?? 负数了

2007-05-17 18:28:27 Ivony...
就是说本来要16行的代码,我减少到1行

2007-05-17 18:28:42 jyk
100行代码,减少了 1500% ,还有代码了吗?呵呵

2007-05-17 18:29:02 Ivony...
减少1500%,当然,从另一个基数来说,可以说减少85%以上

2007-05-17 18:29:26 添先盼
这个还是别争了,哈哈,大伙明白意思就ok

2007-05-17 18:29:31 Ivony...
以后都用大数表达为基数好了……

2007-05-17 18:29:46 Ivony...
不妨来比一比……

2007-05-17 18:30:00 Ivony...
我们抛开连接字符串的存储、数据访问框架的初始化

2007-05-17 18:30:33 Ivony...
我们只靠一个简单的问题,从用户表中取出一行数据,通过用户名

2007-05-17 18:30:56 jyk
一行代码就ok了
 

2007-05-17 18:31:00 jyk
我的方法

2007-05-17 18:31:07 Ivony...
要求使用参数化查询,没有存储过程,SQL语句为:SELECT * FROM User WHERE username = @username

2007-05-17 18:31:21 Ivony...
大家列出自己的代码,看看哪个得最简洁……

2007-05-17 18:31:59 Ivony...
记住,是取出一行代码,要求结果是DataRow或者其他仅包含一行数据的类型

2007-05-17 18:32:27 Ivony...
不能是DataTable或者DataReader这种需要自己关闭的东西。

2007-05-17 18:32:30 jyk
string[] str = DAL.RunSqlStrings(SELECT * FROM User WHERE username='"+ username +"'")
 

2007-05-17 18:32:46 Ivony...
你丢失了类型信息……

2007-05-17 18:32:48 jyk
DataRow dr = DAL.RunSqlDataRow(SELECT * FROM User WHERE username='"+ username +"'")

2007-05-17 18:32:59 Ivony...
且,没有采取参数化查询……

2007-05-17 18:33:15 jyk
我没有用参数化的

2007-05-17 18:33:19 Ivony...
添先盼

2007-05-17 18:33:23 Ivony...
你的呢?

2007-05-17 18:33:31 添先盼
稍等

2007-05-17 18:33:38 Ivony...
那会有注入式漏洞,你处理这些的代码就不少……

2007-05-17 18:33:41 Ivony...
还有很多隐患……

2007-05-17 18:33:48 jyk
类型信息 ?? 有哇 ,第一个是 string[]
第二个是 DataRow

2007-05-17 18:33:49 Ivony...
请消除这些隐患……

2007-05-17 18:34:20 jyk
string username = "";
username = username.Replace("'","");
就可以了

2007-05-17 18:34:33 jyk
我一直是这么用的

2007-05-17 18:34:41 Ivony...
DataRow的确可以保留类型信息

2007-05-17 18:34:49 Ivony...
那么,这些代码也要算上……

2007-05-17 18:35:02 Ivony...
还有,你的整型要区别对待,不麻烦么?

2007-05-17 18:35:02 jyk
类型信息  到底指的是什么呀

2007-05-17 18:35:19 添先盼
呵呵,我的方法跟jyk类似的。中间加了一层页面处理(复杂字符过滤等功能)来处理。

2007-05-17 18:35:28 Ivony...
还有这样写的话,你原数据中的单引号没有了……

2007-05-17 18:35:40 jyk
if (!Functions.IsInt(meInt))

2007-05-17 18:35:46 Ivony...
使用参数化查询的DbUtility,你们猜有多长?

2007-05-17 18:35:48 jyk
这样判断数字

2007-05-17 18:35:57 Ivony...
还有这样写的话,你原数据中的单引号没有了……

2007-05-17 18:36:05 添先盼
嗯,很耐心的在听

2007-05-17 18:36:41 jyk
95%以上都是不会有 单引号的

2007-05-17 18:36:53 jyk
有的话就替换成两个

2007-05-17 18:36:53 添先盼
Ivony?

2007-05-17 18:36:57 Ivony...
黑客攻击的时候会是0%

2007-05-17 18:37:00 Ivony...
dbUtility.ExecuteSingleRow( "SELECT * FROM User WHERE username = {0}", username );

2007-05-17 18:37:16 Ivony...
如此而已,没有任何一行多余的代码

2007-05-17 18:37:27 添先盼
dbUtility是静态类?

2007-05-17 18:37:42 添先盼
还是ExecuteSingleRow是静态方法?

2007-05-17 18:37:49 jyk
对了,我们好像讨论过这个问题

2007-05-17 18:38:10 Ivony...
是实例对象,但是他的初始化很简单,并且,只需要写一次,而且它并非不能做成静态,完全为了其他的方面考虑

2007-05-17 18:38:25 添先盼
哦,那没关系,我自己看看好了 。

2007-05-17 18:38:33 添先盼
能否给个地址。

2007-05-17 18:38:40 Ivony...
实例化代码如下:DbUtility dbUtility = new SqlDbUtility( "连接字符串" );

2007-05-17 18:38:55 Ivony...
你可以写在DataProvider的任何地方

2007-05-17 18:39:16 Ivony...
只需一个实例,不会有线程冲突,这是很罕见的一个内部处理线程冲突的类。

2007-05-17 18:39:51 Ivony...
更复杂的应用才能体现它的威力

2007-05-17 18:40:07 添先盼
Ivony,想请教一下什么工作?工作职责是什么。

2007-05-17 18:40:19 Ivony...
???

2007-05-17 18:40:34 添先盼
呵呵,只是好奇。

2007-05-17 18:41:00 Ivony...
基本上,解决不了的问题归我解决……

2007-05-17 18:41:11 Ivony...
这样的回答满意否?

2007-05-17 18:41:38 jyk
厉害呀

2007-05-17 18:41:53 添先盼
呵呵,太抽象了些。

2007-05-17 18:42:00 Ivony...
与DbUtility相比,SqlHelper垃圾到极点,不仅仅是因为DbUtility节省代码,美观大方。

2007-05-17 18:42:11 添先盼
再比如

2007-05-17 18:42:16 jyk
SqlHelper 的效率相当成问题

2007-05-17 18:42:27 Ivony...
最重要的原因是!!!DbUtility实现这些功能的代码比SqlHelper一点儿也不多……

2007-05-17 18:42:50 Ivony...
也就是说DbUtility代码更少,而功能更强大……

2007-05-17 18:43:08 Ivony...
这样看来,SqlHelper可以说是垃圾到极点了……

2007-05-17 18:44:01 jyk
往往是越拉记得用的人越多,没办法呀

2007-05-17 18:44:36 Ivony...
关键是大家都以为Enterprise Library是微软出的……

2007-05-17 18:45:00 添先盼
呵呵,怪我见少。

2007-05-17 18:45:08 Ivony...
其实这个垃圾不过是微软一个合作伙伴出的一个.NET范例项目而已,而这个范例项目还有点儿烂……

2007-05-17 18:45:22 Ivony...
我研究过EL

2007-05-17 18:45:49 添先盼
感觉?

2007-05-17 18:46:11 Ivony...
头重脚轻

2007-05-17 18:46:13 jyk
类型信息  到底指的是什么呀 

2007-05-17 18:46:15 Ivony...
主次不分

2007-05-17 18:46:28 Ivony...
结构混散

2007-05-17 18:46:38 添先盼
在你看来,什么应该是主要呢?

2007-05-17 18:46:44 添先盼
我也想指导。

2007-05-17 18:47:08 Ivony...
对于数据访问层,DbUtility的设计宗旨就是让程序员干自己该干的事情……

2007-05-17 18:47:15 Ivony...
什么是程序员该干的事情?

2007-05-17 18:47:19 Ivony...
就是设计查询。

2007-05-17 18:47:37 Ivony...
而不是防注入漏洞、创建DbCommand等。

2007-05-17 18:48:00 添先盼
DbUtility怎样兼容多种数据库可能是我比较关心的。

2007-05-17 18:48:07 Ivony...
所以DbUtility把这些乱七八糟的问题全揽在自己身上,程序员只需要设计SQL语句就行了……

2007-05-17 18:48:24 Ivony...
它有不同的版本,SqlDbUtility、OracleDbUtility

2007-05-17 18:48:42 Ivony...
但有相同的接口和共同的基类DbUtility

2007-05-17 18:48:43 添先盼
之前你写出的那个语句,让我想到很早之前使用的一个orm

2007-05-17 18:48:52 添先盼
哦,sodisne

2007-05-17 18:49:23 添先盼
jyk,有什么问问题么?

2007-05-17 18:49:24 Ivony...
DbUtility我觉得发展到现在最大的优势就是它从没头脑发热去搞ORM

2007-05-17 18:49:36 添先盼
嗯,这点比较赞同。

2007-05-17 18:49:43 Ivony...
把SQL拼接玩到了极致……

2007-05-17 18:50:00 Ivony...
就比ORM更实用……

2007-05-17 18:50:27 Ivony...
回答jyk的问题,如果不是从C语言转过来的,对类型一般都不会很敏感

2007-05-17 18:50:39 添先盼
我记得有一个orm就宣称拼接sql语句很强的。

2007-05-17 18:50:42 添先盼
让我想想

2007-05-17 18:50:48 Ivony...
但是不管怎样,.NET Framework是强类型的。

2007-05-17 18:51:22 jyk
Ivony... 18:48:24
它有不同的版本,SqlDbUtility、OracleDbUtility
Ivony... 18:48:42
但有相同的接口和共同的基类DbUtility
======
和我的思路是一样的

2007-05-17 18:51:38 Ivony...
类型携带了很多信息,即使是值类型,携带的这些信息也是很有用的。

2007-05-17 18:52:01 添先盼
现在的这种类大多是这样设计的,而且这也是遵从模式设计的基本方式。

2007-05-17 18:52:25 添先盼
当然,我只是纸上谈兵啦。

2007-05-17 18:52:30 Ivony...
模板方法设计模式

2007-05-17 18:52:40 Ivony...
一个非常显著的地方就是DateTime可以选择任何输出格式呈现,但它一旦ToString,那么他的格式就固定了……

2007-05-17 18:53:02 添先盼
嗯,jyk怎么降到c的呢?

2007-05-17 18:53:08 添先盼
讲到C的呢?

2007-05-17 18:53:13 Ivony...
当然你可以转换回去,但是没有人能保证在转换中没有丢失信息,如浮点型……

2007-05-17 18:54:46 Ivony...
DbUtility在完成代码整理后,会开源……

2007-05-17 18:54:54 添先盼
DbUtility有oledb版本么?

2007-05-17 18:55:00 Ivony...
没有……

2007-05-17 18:55:03 Ivony...
也不会有……

2007-05-17 18:55:06 jyk
不会吧

2007-05-17 18:55:09 添先盼
Why?

2007-05-17 18:55:19 Ivony...
因为只会有AcessDbUtility

2007-05-17 18:55:22 添先盼
开源了就可以自己加了,哈哈。

2007-05-17 18:55:24 Ivony...
MySqlDbUtility

2007-05-17 18:55:34 Ivony...
这一点很重要

2007-05-17 18:55:47 Ivony...
因为即使都是OleDbUtility,

2007-05-17 18:55:47 jyk
其实吧 Sql 替换为 OleDb oledb 版的了吧

2007-05-17 18:55:52 添先盼
针对每种数据库做优化?

2007-05-17 18:56:03 Ivony...
但它们的SQL语法却是不同的

2007-05-17 18:56:05 Ivony...
对头……

2007-05-17 18:56:19 添先盼
有点意思

2007-05-17 18:56:22 Ivony...
针对不同的数据库优化是目的之一,SQL优化……

2007-05-17 18:56:32 添先盼
这肯定跟dbUtility的初衷有关了。

2007-05-17 18:56:40 Ivony...
而根本原因在于SQL语法不同

2007-05-17 18:56:53 Ivony...
因为DbUtility不仅仅是简单的拼接SQL

2007-05-17 18:56:55 Ivony...
还有解析SQL

2007-05-17 18:57:05 Ivony...
例如,

2007-05-17 18:57:10 Ivony...
我举实例吧

2007-05-17 18:57:12 添先盼
能否说一下sql语句执行的一般过程

2007-05-17 18:57:15 Ivony...
现在有个需求

2007-05-17 18:58:35 Ivony...
我有一个字符串数组存放了一堆用户名,我现在想要把数据库中这些用户的信息给取出来

2007-05-17 18:58:41 Ivony...
很显然需要IN语法

2007-05-17 18:58:59 Ivony...
但是输入是不确定的。DbUtility怎么做的?

2007-05-17 18:59:33 Ivony...
DbUtility.

2007-05-17 18:59:43 Ivony...
我写展开的形式,看透逻辑

2007-05-17 19:00:46 Ivony...
DbUtility.ExecuteData( "SELECT * FROM User WHERE username {0}", new InExpression( new ParameterListExpression ( usernames ) ) );

2007-05-17 19:01:17 Ivony...
DbUtility.ExecuteData( "SELECT * FROM User WHERE {0}", new InExpression( Fields.Username, new ParameterListExpression ( usernames ) ) );

2007-05-17 19:01:21 Ivony...
应该是这样

2007-05-17 19:01:38 Ivony...
new InExpression( Fields.Username, new ParameterListExpression ( usernames ) )

2007-05-17 19:01:42 添先盼
你是说这两种都可以?

2007-05-17 19:01:50 Ivony...
应该是下面哪种……

2007-05-17 19:02:08 Ivony...
因为这一部分还没确定,都在测试,所以一时写错了

2007-05-17 19:02:29 添先盼
i know

2007-05-17 19:02:31 Ivony...
new InExpression( Fields.Username, new ParameterListExpression ( usernames ) )
这里,创建一个IN表达式,并将一堆参数传进去。

2007-05-17 19:02:52 AfritXia
DbUtility 的设计是不是和数据库耦合的太紧了?万一数据库里根本就没有 UserName 这个字段怎么办?

2007-05-17 19:03:21 添先盼
Fields是什么类?跟数据表相关么?

2007-05-17 19:03:46 Ivony...
这个时候,不同的数据库IN的语法、字段的表示(SQL Server是[username]、MySql是`username`)都不同,所以必须针对不同的数据库处理

2007-05-17 19:03:58 添先盼
明白

2007-05-17 19:04:19 Ivony...
Fields是DbUtility另一个项目DBSchemaDom的产物

2007-05-17 19:04:45 AfritXia
如此说来,ParameterListExpression 应该作为一个抽象类比较合适

2007-05-17 19:05:02 Ivony...
用于描述某个数据库的架构,供DbUtility的SqlDom创建类型安全的表达式对象

2007-05-17 19:05:17 AfritXia
在具体的数据库里,才被真正的赋予一种表达逻辑

2007-05-17 19:05:46 Ivony...
呵呵……如果你认真研究CodeDom就会发现这个类不需要抽象……

2007-05-17 19:05:59 Ivony...
因为它被解释成什么样子完全取决于DbUtility

2007-05-17 19:06:20 Ivony...
准确的说是DbUtility的CommandParser

2007-05-17 19:07:06 Ivony...
也就是说SqlDbUtility和MySqlDbUtility在处理这些对象的时候,将它们生成成SQL语句的时候,是不同的……

2007-05-17 19:07:28 AfritXia
Fields 也用到了 CodeDom 技术?

2007-05-17 19:07:31 添先盼
哦,这样讲,很有兴趣研究一下。

2007-05-17 19:07:43 Ivony...
这就是DbUtility针对不同数据库创建不同的类型的根本原因

2007-05-17 19:07:52 Ivony...
而不是根据不同的DataProvider。

2007-05-17 19:08:05 Ivony...
是与CodeDom类似的技术……

2007-05-17 19:08:13 Ivony...
我们称之为SchemaDom和SqlDom

2007-05-17 19:08:33 Ivony...
一个是架构文档对象模型

2007-05-17 19:08:42 Ivony...
一个是SQL查询文档对象模型……

2007-05-17 19:08:55 AfritXia
那么 SQLDBUtility 和 DBUtility 是什么关系?

2007-05-17 19:08:59 添先盼
着手研究DbUtility有研究的代码么?

2007-05-17 19:09:08 Ivony...
前者是后者的派生类……

2007-05-17 19:09:29 AfritXia
扩展了那些内容,可以大概说一下吗?

2007-05-17 19:09:57 Ivony...
嗯……主要有几方面的扩展

2007-05-17 19:10:23 Ivony...
首先是数据库专用功能,如SqlServer支持的特色功能,SQL特有函数表达式等。

2007-05-17 19:10:29 东东
[share]JYK的新群

2007-05-17 19:11:11 东东
.net中,NHibernate用的多吗

2007-05-17 19:11:18 Ivony...
其次是每一个DbUtility的派生类理论上都有自己的CommandParser类,当然,SqlCommandParser同样继承于CommandParser,使用一些公有功能。

2007-05-17 19:12:18 AfritXia
DBUtility 是怎么处理事务的?

2007-05-17 19:12:21 Ivony...
还有就是存储过程的支持,每一个数据库的DbUtility都有所配套的StoredProducer类来帮助访问存储过程,当然,不支持存储过程的数据库除外

2007-05-17 19:13:12 Ivony...
架构分析生成打算是另外一个工具来自动生成代码,但DbUtility要提供协助。

2007-05-17 19:14:01 Ivony...
事务也是DbUtility很漂亮的一个地方,不过,事务并不是所有的数据库都支持,所以DbUtility现在只提供了一种推荐写法由SqlDbUtility实现。

2007-05-17 19:14:49 AfritXia
对于 Access 数据库来说,DBUtility 是否支持事务?

2007-05-17 19:14:59 Ivony...
transaction = dbUtility.BeginTransaction;
transaction.ExecuteNonQuery( "你要执行的代码" );
transaction.ExecuteNonQuery( "可以执行多个" );
transaction.Commit。

2007-05-17 19:15:11 Ivony...
数据库不支持,DbUtility是没办法支持的……

2007-05-17 19:15:26 AfritXia
啊?

2007-05-17 19:15:34 Ivony...
transaction = dbUtility.BeginTransaction
transaction.ExecuteNonQuery( "你要执行的代码" );
transaction.ExecuteNonQuery( "可以执行多个" );
transaction.Commit;

2007-05-17 19:15:41 Ivony...
当然,我们在考虑设计批处理

2007-05-17 19:15:43 jyk
打了一个电话的功夫,讨论就这么热烈了呀

2007-05-17 19:15:57 Ivony...
即一次执行多条SQL

2007-05-17 19:16:33 Ivony...
DbUtility每一处设计都从代码美观的角度出发。

2007-05-17 19:16:43 AfritXia
这个 Transaction 是什么类型的?

2007-05-17 19:16:53 AfritXia
DbTransaction ??

2007-05-17 19:16:54 Ivony...
还是SqlDbUtility

2007-05-17 19:17:09 Ivony...
所以SqlDbUtility有的它都有……

2007-05-17 19:17:34 Ivony...
虽然看起来有些古怪,但用起来却挺直观,没有什么问题。

2007-05-17 19:18:45 添先盼
很好的销售人才

2007-05-17 19:18:46 Ivony...
它与原来的那个dbUtility的区别仅在于,Commit和RollBack方法可用了,还有,Dispose会回滚事务,以及,AllwaysCreateNewConnction这个属性值恒为false,不可更改

2007-05-17 19:19:36 Ivony...
AllwaysCreateNewConnction这个属性用来指示DbUtility是否对每一次数据库操作创建一个新的连接,这在ASP.NET环境中是很重要的……

2007-05-17 19:20:00 Ivony...
但是在WinForm中,处于效率考虑,你可以关掉它……

2007-05-17 19:20:09 jyk
终于跟上了

2007-05-17 19:20:22 Ivony...
而在事务中,是不可能创建新的连接的,所以它被禁用。

2007-05-17 19:21:12 jyk
问一下:我可不可以把这里的讨论发布到网上?

2007-05-17 19:21:23 jyk
讨论太精彩了

2007-05-17 19:21:35 Ivony...
我不保留版权……

2007-05-17 19:21:42 Ivony...
询问其他讨论者意见

2007-05-17 19:21:46 jyk
那就是可以发了。

2007-05-17 19:21:49 AfritXia
如果另外一个线程进来了,那么是否需要等待 connection 释放掉才可以继续执行?

2007-05-17 19:21:57 Ivony...
???

2007-05-17 19:22:07 Ivony...
DbUtility会随手关掉Connection

2007-05-17 19:22:20 Ivony...
在AllwaysCreateNewConnection的情况下

2007-05-17 19:22:20 jyk
你是主说,你都同意了,其他人应该是没有意见的吧。

2007-05-17 19:22:24 Ivony...
会随手销毁……

2007-05-17 19:22:40 添先盼
没问题

2007-05-17 19:24:08 Ivony...
DbUtility的SqlDom是一个很大的基础工程,它让SQL可以被自动生成,从而给上层应用提供很好的平台。
例如:
QueryExpression query = QueryExpressionBuilder.Select ( Fields.AllFields ).Where( Fields.Username == "Ivony" );

2007-05-17 19:24:17 Ivony...
然后:

2007-05-17 19:24:32 Ivony...
dbUtility.ExecuteSingleRow( query );

2007-05-17 19:25:00 Ivony...
这样生成出来的SQL语句,才可以说是真正跨数据库兼容的……

2007-05-17 19:25:52 jyk
top 10 问题是怎么处理的呢?因为 Orcale 是没有 top 的呀

2007-05-17 19:26:23 Ivony...
那就不能用,或者CommandParser将其解析成更复杂的SQL语句来实现。

2007-05-17 19:26:28 AfritXia
我还有个问题,如果此次事务还没有执行完,而下一个线程进来了,也要执行相同的事务,那么数据库联接是怎么被处理的?

2007-05-17 19:27:00 Ivony...
dbUtility.BeginTransaction方法会创建一个新的dbUtility对象

2007-05-17 19:27:22 jyk
可是对于 MS SQL 来说 top 是很常用的呀,而且很方便

2007-05-17 19:27:24 Ivony...
每个DbUtility对象中都有一个Connection,就是这么解决的。

2007-05-17 19:27:38 AfritXia
明白了

2007-05-17 19:27:43 Ivony...
你如果真的需要跨数据库兼容,就不得不放弃一些东西

2007-05-17 19:28:23 AfritXia
最后一个问题,如果数据库字段增加或减少,那么需要通过 CodeDom 技术来修改 Fields 类?

2007-05-17 19:28:43 Ivony...
继续上文。当然,大家可能还是看到了语法比较繁杂,但C# 3.0出来后应该可以有所改善,不过,值得注意的是,这个SqlDom可不是让我们自己调用的,他的设计初衷就是为上层应用,如自动生成SELECT语句等应用设计的。

2007-05-17 19:29:24 Ivony...
到时候会有一个外部工具来读取数据库架构并将这些架构生成为类结构。暂定是这样

2007-05-17 19:30:45 Ivony...
我所说的上层应用就包括真正的ORM,如根据类,生成数据库结构,并产生查询修改语句,以及产生查询界面等等……

2007-05-17 19:31:15 Ivony...
如果有SqlDOM的支持,我们就不怕那是梦想……

2007-05-17 19:31:55 AfritXia
也就是说 同名字段名称 会以 类名称加以区别了,类如:

Customer.UserName
Developer.UserName

2007-05-17 19:32:44 Ivony...
我很希望能将这些语法简化,正在研究C#3.0的lambda表达式,希望能解决这些问题。

2007-05-17 19:33:14 Ivony...
或者直接使用C# 3.0的 DLINQ模型,关注ing……

2007-05-17 19:33:32 添先盼
大家同样很关注,呵呵。

2007-05-17 19:33:44 jyk
C# 3.0 又有很大的变化吗

2007-05-17 19:34:03 jyk
2.0还没熟呢

2007-05-17 19:35:07 添先盼
呵呵,技术总是先走一步嘛,更别说这是微软的主打了。

2007-05-17 19:36:44 Ivony...
lambda是重头戏

2007-05-17 19:46:24 jyk
辛苦了

相关文章
|
JSON IDE 机器人
超简单:mac导出微信聊天记录(附上粉丝群全部聊天记录)
今天再给大家讲解一下如何直导出mac版本微信的聊天记录,当然如果你没有mac,那可以直接关闭这篇文章了。
9047 0
超简单:mac导出微信聊天记录(附上粉丝群全部聊天记录)
|
设计模式 Java uml
微信和QQ这么多群,该如何管理好友关系?
在现实生活中,中介者的存在是不可缺少的,如果没有了中介者,我们就不能与远方的朋友进行交流。各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互,则会形成如下图所示的网状结构。
117 1
|
自然语言处理 算法 数据安全/隐私保护
教你如何用代码自动群发邮件(邮件轰炸机)
教你如何用代码自动群发邮件(邮件轰炸机)
1296 0
教你如何用代码自动群发邮件(邮件轰炸机)
|
6月前
|
开发者
【公告】阿里云开发者社区“关注后查看全文”功能调整通知
12月8日阿里云开发者社区将关闭博主“关注后查看全文”功能
|
运维 测试技术
【超干货】近期收到的测试面试题分析
【超干货】近期收到的测试面试题分析
|
应用服务中间件 nginx
微信公众号能正常回复消息,但是依旧提示该公众号提供的服务出现故障,请稍后再试
前两天公众号突然抽风了,虽然消息能正常回复,但是依旧提示提示该公众号提供的服务出现故障,请稍后再试
475 0
微信公众号能正常回复消息,但是依旧提示该公众号提供的服务出现故障,请稍后再试
为什么明明是发自己的博客,阿里却删除我发部的开源作品?
为什么明明是发自己的博客,阿里却删除我发部的开源作品?
1035 0
|
数据采集 数据可视化 Python
如何利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例
前几天给大家分享了利用Python网络爬虫抓取微信朋友圈的动态(上)和利用Python网络爬虫爬取微信朋友圈动态——附代码(下),并且对抓取到的数据进行了Python词云和wordart可视化,感兴趣的伙伴可以戳这篇文章:利用Python词云和wordart可视化工具对朋友圈数据进行可视化。
1727 0
|
Web App开发 JSON JavaScript
C# 获取QQ群数据的实现
一,分析 1,群数据获取         当访问http://qun.qq.com/air/#mygroup我们通过Fiddler可以查看到QQ群列表是从http://qun.qq.com/air/group/mine?w=a这个URL获取到的群列表信息               其中返回的js...
1062 0