小妖女 发表于 2015-1-16 22:45:49

ASP.NET网页编程之在C#中创建庞大的、天真的SQL查询/命令...

java的设计机制:首先产生一个中间码,第二部编译为本地(机器)码。这个机制有很大的缺点。sql<P>  SelectQueryBuilder类同意在你的代码中创建庞大的SQL语句和命令。它也能匡助于制止SQL注进式打击。

  先容

  供认,而且我们都如许作过,也以为上面的体例是最好的和独一的体例。就是我们创建大批的字符串包括一切的Where子句,然后提交到数据库往实行它。来断的加语句到我们的SQL字符串,极有大概会带来Bugs和SQL注进式打击的伤害。而且也使得我们的代码更丢脸也不容易于办理。

  这类情形必需中断,但怎样中断?有人说利用存储历程。但它并没有真实的办理这个成绩。你还得静态创建你的SQL语句,只不外有成绩移到数据库层面上了,仍然有SQL注进的伤害。除这个“办理计划”外,大概另有十分多的选择供你思索,但它们城市带来一个基础的应战:让SQL语句事情的更好、更平安。

  当我从我的在线DAL(数据会见层)天生工具http://www.code-engine.com/创建C#模板时,我想供应一个易于利用的办法来定制查询数据。我不再想利用“字符串查询”(我之前开辟的模板)来查询数据。我腻烦这类混乱的体例来失掉数据。我想用一种明晰的、直觉的、天真的、复杂的体例从表当选择数据,连接一些其余语句,利用大批的Where子句,用一些列来分组数据,前往前X个纪录。

  我入手下手开辟所想的有这类周密功效的SelectQueryBuilder类。它表露了很多属性和办法,你能很简单地在Select语句中利用它们。一旦挪用BuildQuery()和BuildCommand()办法,它能供应一种更好的旧的“字符串查询“或可使用命令参数的DbCommand工具来查询数据。

  利用代码

  旧的体例的代码

  上面的代码分析了之前创建SELECT语句的办法,它利用很多类变量来讲明应当利用那种毗连操纵(WHERE,大概OR),同时也给你的数据库带来了大概的SQL注进式打击。

stringstatement="SELECTTOP"+maxRecords+"*FROMCustomers";
stringwhereConcatenator="WHERE";
if(companyNameTextBox.Text.Length>0)
{
 statement+=whereConcatenator;
 statement+="CompanyNamelike"+companyNameTextBox.Text+"%";
 whereConcatenator="AND";
}

if(cityTextBox.Text.Length>0)
{
 statement+=whereConcatenator;
 statement+="Citylike"+cityTextBox.Text+"%";
 whereConcatenator="AND";
}
if(countryComboBox.SelectedItem!=null)
{
 statement+=whereConcatenator;
 statement+="Country="+countryComboBox.SelectedItem+"";
 whereConcatenator="AND";
}
  我信任下面的代码对你来讲长短常熟习的,你大概在已往的十多年一向是如许利用的,大概你已经编码过数据库驱动的搜刮功效。让我告知你这类头脑:这类查询你的数据库的办法不克不及再利用了,它是丢脸的也是不平安的。

  SelectQueryBuilder体例的代码

  一样的查询可以利用SelectQueryBuilder类创建。

SelectQueryBuilderquery=newSelectQueryBuilder();
query.SelectFromTable("Customers");
query.SelectAllColumns();
query.TopRecords=maxRecords;
if(companyNameTextBox.Text.Length>0)
 query.AddWhere("CompanyName",Comparison.Like,companyNameTextBox.Text+"%");
 if(cityTextBox.Text.Length>0)
  query.AddWhere("City",Comparison.Like,
  cityTextBox.Text+"%");
 if(countryComboBox.SelectedItem!=null)
  query.AddWhere("Country",Comparison.Equals,
  countryComboBox.SelectedItem);
  stringstatement=query.BuildQuery();
  //or,haveaDbCommandobjectbuilt
  //forevenmoresafetyagainstSQLInjectionattacks:
  query.SetDbProviderFactory(
  DbProviderFactories.GetFactory(
  "System.Data.SqlClient"));
  DbCommandcommand=query.BuildCommand();
  你能看到,这类体例比间接利用毗连字符串更直不雅。思索到第一个例子SQL注进的伤害,经由过程SelectQueryBuilder创建的SELECT查询长短常平安的,其实不用忧虑利用的TextBoxs中的内容。现实上它也十分复杂!

  利用SQL函数

  假如你想在你的查询中利用SQL函数,你能利用SqlLiteral类来打包函数的挪用。申明这个类能作甚么的最好体例就是给你显现一小段代码例子:

SelectQueryBuilderquery=newSelectQueryBuilder();
query.SelectFromTable("Orders");
query.AddWhere("OrderDate",Comparison.LessOrEquals,newSqlLiteral("getDate()"));
  假如我们没有打包getDate()函数挪用到SqlLiteral类中,创建的查询就会发生WHERE子句:OrderDate<=’getDate()’。固然,我们但愿在语句中的这个函数没有被单引号包抄。这时候SqlLiteral就能够派上用处了:它间接拷贝字符串到输入,并没有把它格局化成字符串。如今的输入WHERE子句应该是OrderDate<=getDate()!

  查询中利用JOINs

  要创立到别的表的JOINs,你能利用AddJoin办法。上面的代码显现了怎样创立一个从Ordres表到Customers表的INNERJOIN。

SelectQueryBuilderquery=newSelectQueryBuilder();
query.SelectFromTable("Orders");
query.AddJoin(JoinType.InnerJoin,"Customers","CustomerID",Comparison.Equals,"Orders","CustomerID");
query.AddWhere("Customers.City",Comparison.Equals,"London");
  这段代码选择一切寓居在London的客户的定单。一旦挪用了BuildQuery办法,就会发生上面的SQL语句:

SELECTOrders.*
FROMOrders
INNERJOINCustomersONOrders.CustomerID=Customers.CustomerID
WHERE(Customers.City=London)
  注重到缺省的查询只会创建所选择的表的selects*语句(这个例子中的Orders.*)。假如你也想选择毗连表的列的话,你必需得显式地选择它们。你能通用挪用query.SelectColumns(“Orders.*”,”Customers.*”)。
<P>  创建盘算查询

  假如你想对你的数据库实行一个盘算查询。你能利用SelectCount办法好像上面显现的:

  Query.SelectCount();

  在加倍庞大的盘算查询中,你大概想利用GROUPBY语句。看一下上面的例子,它显现了怎样利用GroupBy和AddHaving办法。

SelectQueryBuilderquery=newSelectQueryBuilder();
query.SelectColumns("count(*)ASCount","ShipCity");
query.SelectFromTable("Orders");
query.GroupBy("ShipCity");
query.AddHaving("ShipCity",Comparison.NotEquals,"Amsterdam");
query.AddOrderBy("count(*)",Sorting.Descending);
  下面的代码选择了每一个乡村的定单数,并用定单数量排序,不思索来便宜Amsterdam的定单,BuildQuery办法的输入了局应该是:

SELECTcount(*)ASCount,ShipCity
FROMOrders
GROUPBYShipCity
HAVING(ShipCityAmsterdam)
ORDERBYcount(*)DESC
  庞大的Where语句

  假如你已经用过微软的Access或SQLServer的内置的查询天生器的话,是不是惊奇你能创建和代码一样的包括多层ANDs和Ors,并没有体贴()标记的地位的查询?是的?我也能!

  你能利用SelectQueryBuilder类完成!你能加多层的WHERE语句到你的查询。缺省,一切对query.AddWhere的挪用被放在查询的第一层上。你能够把它比作SQLServer查询天生器的’Criteria’列;第2、3、四层等响应地对应于’Or…’列。

  看一下上面的SQLServer查询天生器的快照,经由过程它我能疾速地把复杂的假的SELECT语句放在一同来:

  如你看到的,我创立一个查询,它选择一切在1-1-2005日期之前的客户’VINET’的定单,和一切30-6-2004日期之前或1-1-2006日期以后的客户’TOMSP’的定单(请不要问为何有人想查询某团体的定单,这仅仅是一个例子)。这个查询可以创建:

SelectQueryBuilderquery=newSelectQueryBuilder();
query.SelectFromTable("Orders");
//AddCriteriacolumntolevel1
query.AddWhere("CustomerID",Comparison.Equals,"VINET",1);
query.AddWhere("OrderDate",Comparison.LessThan,newDateTime(2005,1,1),1);
//AddfirstOr...columntolevel2
query.AddWhere("CustomerID",Comparison.Equals,"TOMSP",2);
query.AddWhere("OrderDate",Comparison.LessThan,newDateTime(2004,6,30),2);
//AddsecondOr...columntolevel3
query.AddWhere("CustomerID",Comparison.Equals,"TOMSP",3);
query.AddWhere("OrderDate",Comparison.GreaterThan,newDateTime(2006,1,1),3);
  当挪用BuildQuery时,一切界说的层将被OR到一同,几近和SQLServer天生的一样。

  假如你到所发生的语句靠近一样时,想让查询更庞大,你大概会说“我的放两个随后的语句一同放在一个语句中,在两个日时代利用OR”。你可以如许作。在SQLServer查询天生器中,这个查询看起来像:

  一样,它也大概利用SelectQueryBuilder经由过程创立’嵌套的WHERE子句’来完成。

SelectQueryBuilderquery=newSelectQueryBuilder();
query.SelectFromTable("Orders");
//AddCriteriacolumntolevel1
query.AddWhere("CustomerID",Comparison.Equals,"VINET",1);
query.AddWhere("OrderDate",Comparison.LessThan,
newDateTime(2005,1,1),1);
//AddOr...columntolevel2
query.AddWhere("CustomerID",
Comparison.Equals,"TOMSP",2);
//Addthedateselectionclause
WhereClauseclause=query.AddWhere("OrderDate",Comparison.LessThan,
  newDateTime(2004,6,30),2);
//Addanestedclausetothecapturedclause
clause.AddClause(LogicOperator.Or,
Comparison.GreaterThan,newDateTime(2006,1,1));
  注重到我用了一个WhereClause工具,它由AddWhere挪用前往。接着挪用clause.AddClause创立一个嵌套的子句柄,而且选择经由过程指定LogicOperator.Or来把它OR到第一个子句上。所发生的语句以下:

SELECTOrders.*
FROMOrders
WHERE
(
 (CustomerID=VINET)
 AND(OrderDate<2005/01/0112:00:00)
)
OR
(
 (CustomerID=TOMSP)
 AND(OrderDate<2004/06/3012:00:00OR
 OrderDate>2006/01/0112:00:00)
)
  请注重这个例子中日期包括’12:00:00’,这是由于我在DateTime机关体中疏忽了工夫。但这只需因为我的习气。假如我利用newDateTime(2006,1,1,0,0,0),日期字符串将包括’00:00:00’。

  结论

  在先容中我就提到,SelectQueryBuilder是CodeEngine框架的一部分。这个框架也包括了DeleteQueryBuilder,UpdateQueryBuilder,InsertQueryBuilder。我在经由过程我的C#DAL发生器天生的代码中利用这些天生器。你能从www.code-engine.com高低载一份框架DLL的拷贝。在这时代我也将公布别的的查询天生器的源代码。同时假如你有甚么成绩,评价或倡议,请实时与我接洽。c语言的编译器,几乎是所有新平台都有的。因此从这点上看,c语言的程序,比其他任何语言更加容易跨平台。

精灵巫婆 发表于 2015-1-19 23:03:22

那么,ASP.Net有哪些改进呢?

小女巫 发表于 2015-1-25 14:00:42

现在主流的网站开发语言无外乎asp、php、asp.net、jsp等。

柔情似水 发表于 2015-2-2 22:19:08

是指转换后的Servlet程序代码的行数。这给调试代码带来一定困难。所以,在排除错误时,可以采取分段排除的方法(在可能出错的代码前后输出一些字符串,用字符串是否被输出来确定代码段从哪里开始出错)。

愤怒的大鸟 发表于 2015-2-8 13:26:44

由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。

金色的骷髅 发表于 2015-2-25 15:20:11

在调试JSP代码时,如果程序出错,JSP服务器会返回出错信息,并在浏览器中显示。这时,由于JSP是先被转换成Servlet后再运行的,所以,浏览器中所显示的代码出错的行数并不是JSP源代码的行数。

分手快乐 发表于 2015-3-7 22:54:23

由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。

爱飞 发表于 2015-3-15 16:04:03

ASP.NET:ASP.net是Microsoft.net的一部分,作为战略产品,不仅仅是ActiveServerPage(ASP)的下一个版本;它还提供了一个统一的Web开发模型,其中包括开发人员生成企业级Web应用程序所需的各种服务。ASP.NET的语法在很大程度上与ASP兼容,同时它还提供一种新的编程模型和结构,可生成伸缩性和稳定性更好的应用程序,并提供更好的安全保护。

因胸联盟 发表于 2015-3-22 02:09:15

ASP.Net和ASP的最大区别在于编程思维的转换,而不仅仅在于功能的增强。ASP使用VBS/JS这样的脚本语言混合html来编程,而那些脚本语言属于弱类型、面向结构的编程语言,而非面向对象。
页: [1]
查看完整版本: ASP.NET网页编程之在C#中创建庞大的、天真的SQL查询/命令...