在c#中建立复杂的、灵活的sql查询/命令_c#应用
2008-02-23 05:43:42来源:互联网 阅读 ()
原文地址:http://www.codeproject.com/cs/database/SelectQueryBuilder.asp
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注入式攻击。
string statement = "SELECT TOP " maxRecords " * FROM Customers ";
string whereConcatenator = "WHERE ";
if (companyNameTextBox.Text.Length > 0)
{
statement = whereConcatenator;
statement = "CompanyName like " companyNameTextBox.Text "% ";
whereConcatenator = "AND ";
}
if (cityTextBox.Text.Length > 0)
{
statement = whereConcatenator;
statement = "City like " cityTextBox.Text "% ";
whereConcatenator = "AND ";
}
if (countryComboBox.SelectedItem != null)
{
statement = whereConcatenator;
statement = "Country = " countryComboBox.SelectedItem " ";
whereConcatenator = "AND ";
}
我相信上面的代码对您来说是很熟悉的,您可能在过去的十多年一直是这样使用的,或您曾编码过数据库驱动的搜索功能。让我告诉您这种思想:这种查询您的数据库的方法不能再使用了,他是难看的也是不安全的。
SelectQueryBuilder方式的代码
同样的查询能够使用SelectQueryBuilder类建立。
SelectQueryBuilder query = new SelectQueryBuilder();
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);
string statement = query.BuildQuery();
// or, have a DbCommand object built
// for even more safety against SQL Injection attacks:
query.SetDbProviderFactory(
DbProviderFactories.GetFactory(
"System.Data.SqlClient"));
DbCommand command = query.BuildCommand();
您能看到,这种方式比直接使用连接字符串更直观。考虑到第一个例子SQL注入的危险,通过SelectQueryBuilder建立的SELECT查询是很安全的,并不用担心使用的TextBoxs中的内容。事实上他也很简单!
使用SQL函数
假如您想在您的查询中使用SQL函数,您能使用SqlLiteral类来打包函数的调用。说明这个类能作什么的最好方式就是给您显示一小段代码例子:
SelectQueryBuilder query = new SelectQueryBuilder();
query.SelectFromTable("Orders");
query.AddWhere("OrderDate", Comparison.LessOrEquals,
new SqlLiteral("getDate()"));
假如我们没有打包getDate()函数调用到SqlLiteral类中,建立的查询就会产生WHERE子句:OrderDate<=’getDate()’。当然,我们希望在语句中的这个函数没有被单引号包围。这时SqlLiteral就能够派上用场了:他直接拷贝字符串到输出,并没有把他格式化成字符串。现在的输出WHERE子句应当是OrderDate<=getDate()!
查询中使用JOINs
要创建到其他表的JOINs,您能使用AddJoin方法。下面的代码显示了如何创建一个从Ordres表到Customers表的INNER JOIN。
SelectQueryBuilder query = new SelectQueryBuilder();
query.SelectFromTable("Orders");
query.AddJoin(JoinType.InnerJoin,
"Customers", "CustomerID",
Comparison.Equals,
"Orders", "CustomerID");
query.AddWhere("Customers.City",
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇: 如何获取当前操作系统的软件版本_c#应用
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash