如何使用 ASP.NET 在数据库中搜索相关查询






4.54/5 (11投票s)
本文介绍如何使用 ASP.NET (C#) 在数据库中搜索相关查询。
引言
本文介绍如何使用 ASP.NET 在您的网站和网页中实现 C# 代码,仅用几行代码即可为您的网站提供更好的网络搜索功能。本文解释了您可以使用哪种算法来查找数据库中的内容,并将其提供给用户,这些内容几乎涵盖您数据库中的每个字段。
背景
我看到很多人都在询问如何构建一个更好的搜索引擎,虽然我无法为他们提供 Google 或 Bing 的源代码,但我可以告诉他们搜索引擎实际上是如何工作的(仅限于数据库部分,因为我不会涉及元标签、爬虫和抓取器等),以及它如何根据用户提供给服务器的查询来返回结果。
也许将来,本文能帮助其他开发者为自己的 ASP.NET 网站或公司构建搜索引擎。
环境要求
此项目是使用 WebMatrix 构建的,如果您已将其安装在系统上,则无需担心,继续阅读即可跳过本文的这一部分。如果您没有 WebMatrix,可以随时从 Microsoft 的 Web 平台安装程序中获取。
只需访问 Microsoft 网站(http://www.microsoft.com/web),然后从该位置下载安装程序。完成后,该软件将在您的计算机上安装一个程序。不用担心,只需接受并继续该过程,这将安装 WebMatrix 以及运行此网站在您自己的个人计算机上所需的所有相关软件。否则,此网站项目将无法正常运行,您也无法在计算机上测试此项目。
SQL Server CE 是必需的,因为我们要处理数据库,SQL Server CE 是一个免费的基于文件的数据库,您可以免费获取并使用。如果您要使用 SQL Server Express 或任何其他版本,也可以这样做,只需确保您的项目 web.config 文件中已添加了连接字符串。
什么是搜索引擎
就像所有其他互联网术语一样,这个术语也可能给用户一种关于某种外星事物的强烈煽动感,但请记住,这只是一个英文术语,“搜索引擎”。实际上,它只是一个软件、一种逻辑或算法,用于查找您正在寻找的内容。
例如,Google,它们不是一家外星公司,它们只是一家为您提供您正在查找结果的公司。它们向您询问一个查询,然后针对其数据库运行代码,并查找最佳匹配项。也就是说,它们提取并使用一些特殊的 ASP.NET (C#) 代码来找出哪些结果最适合您。
在个人网站上也可以做类似的事情。您可以为您的工作创建一个数据库,完成后。您可以创建一个表来保存内容。完成后。您将知道在哪里以及如何查找用户所要求的数据。这就是其他公司所做的,它们使用您的查询并在其数据库中查找相关数据。
例如,当您搜索“Christmas”时,它们会搜索包含 Christmas 的所有内容,例如,“Merry Christmas”,然后为您提供“Merry Christmas”的结果。网络服务器上没有黑魔法。它只是一个代码和一些存储在硬盘上的数据。
使用项目
该项目已为您设置好一切,一个简单的搜索字段(虽然不是搜索字段,只是一个输入字段)和一个用于工作的按钮。一旦提交,它将发送到 (IIS) 服务器并请求读取数据库数据。IIS 执行此操作,并将数据返回给请求。然后,响应将生成来自数据库的内容,该内容与查询匹配(或不匹配)。
在此阶段之后,其余工作将由我们 `body` 元素内的代码处理。在这里,我们检查是否有数据,如果有,则查找值和其他内容,等等。
构建数据库
我在本项目中使用的数据库是 SQL Server CE,您可以从 Microsoft 获取并免费使用。但请记住,它(或即将)已弃用。因此,我建议您升级到 SQL Server Express。它也是 Microsoft 的免费数据库,您可以享受 SQL Server 的所有功能。
该数据库只有一个表。它包含我们在匹配时提取的 ID,用于标题搜索的 PostTitle 列,以及用于内容搜索的 PostContent 列。我们将同时搜索它们以获取任何可能的匹配。
注意:这些内容是从我的 WordPress 账户提取的 链接 1 和 链接 2。
使用网站
如前所述,此网站使用一个简单的 HTML 表单,该表单从用户那里获取输入,如下所示,
这是一个空表单,未填写任何值。填写以下值,看看会发生什么,
此表单已填写了足够的信息,现在您可以继续单击“提交”按钮。这样做后,您将看到以下结果。
您可以看到,结果已经出来了,其中至少包含一个“Software”一词的出现。其他已被排除在列表之外。只有相关内容会发布到网站上。还有一个结果显示包含“Software”一词的帖子的内容。因此,此网站会同时搜索标题和内容以获取查询。您可以编辑 UI,使其更适合您的应用程序,可以选择显示标题、内容或两者都显示,就像已经完成的一样!
现在让我们尝试另一个查询,为什么不试试特殊字符查询?尝试在查询框中输入“C#”,然后按搜索按钮,这次您将看到以下结果
这可能看起来与上一个相同,但实际上并非如此。您可以看到这次带有标题的帖子是一个新帖子,实际上是其他内容。因此,您可以看到代码每次都在数据库中搜索新数据,即它不使用缓存服务。它会持续搜索相关数据,并为您提供您正在寻找的准确查询,并丢弃您不想使用的其余项。
那么,如果我们数据库中没有的词呢?
嗯,这是此网站的另一项功能,它不会向您显示任何异常、错误或糟糕的用户体验。它会礼貌地告知您遇到的错误。它会告诉您输入的查询没有结果,就这么简单。
您可以尝试在搜索框中输入“WebMatrix”并进行搜索,将会生成以下页面
这将是 ASP.NET 代码提供的结果,您可以理解目前您没有任何与 WebMatrix 相关的内容,因此您需要向数据库写入一些内容,以便用户可以从您的网站获取有关 WebMatrix 的一些结果。
网站代码
网站代码非常简单,它实际上充当搜索引擎,但功能不那么强大,因为只有少量的服务器端 ASP.NET 代码。它负责数据库处理、查询提取和 UI HTML 渲染。
@{
Layout = "~/_SiteLayout.cshtml";
Page.Title = "Home Page";
}
@{
bool executed = false;
List<int> titleResultStrings = new List<int>();
List<int> contentResultStrings = new List<int>();
if(IsPost) {
// request was made, get the input and search the database.
var query = "%" + Request.Form["input"] + "%";
var db = Database.Open("StarterSite");
// select the Query, parameters on
var selectTitleQuery = "SELECT * FROM Content WHERE PostTitle LIKE @0";
var selectContentQuery = "SELECT * FROM Content WHERE PostContent LIKE @0";
var titleResult = db.Query(selectTitleQuery, query);
var contentResult = db.Query(selectContentQuery, query);
// append the post id to the list
foreach (var row in titleResult) {
titleResultStrings.Add(row.PostId);
}
foreach (var row in contentResult) {
contentResultStrings.Add(row.PostId);
}
// got the content, now do the C# on it!
executed = true;
}
}
<form method="post">
Write the input and get the result!<br />
<input type="text" name="input" /><br />
<input type="submit" value="Submit" />
</form>
// code executed
@if(executed) {
<p>Code has been executed!</p>
// if the code was executed show the result.
if(titleResultStrings.Count() != 0) {
var db2 = Database.Open("StarterSite");
<h4>Posts whose title have this character are</h4>
int i = 0;
foreach (var item in titleResultStrings) {
// get the data for each item!
var post = db2.Query("SELECT * FROM Content WHERE PostId = @0", titleResultStrings[i]);
i++;
foreach (var row in post) {
<p>@row.PostTitle</p>
}
}
} else {
<p>No post for query "<b>@Request.Form["input"]</b>" was found!</p>
}
if(contentResultStrings.Count() != 0) {
var db2 = Database.Open("StarterSite");
<h4>Posts whose content have this character are</h4>
int i = 0;
foreach (var item in contentResultStrings) {
// get the data for each item!
var post = db2.Query("SELECT * FROM Content WHERE PostId = @0", contentResultStrings[i]);
i++;
foreach (var row in post) {
<p>@row.PostContent</p>
}
}
} else {
<p>No post for query "<b>@Request.Form["input"]</b>" content was found!</p>
}
}
一旦您了解了代码,它就非常容易。它只有 20% 的算法、30% 的数据库提取和查询管理,以及 50% 的用于查看结果的 HTML 渲染。
防止 SQL 注入
SQL 注入是黑客用来破坏您的 SQL 查询并损害您数据库的一种方法。有许多类型的注入可能会编辑您数据库中的内容、更新它,甚至删除您的表。数据库搜索的示例查询是
var result = db.Query("SELECT * FROM table_name WHERE column_name = value");
如果您传入有效值,它将正确执行。但如果用户尝试传入一个可能破坏查询的值,则整个数据库可能会被服务器暴露给他。假设值为:“'; DROP TABLE table_name --”。
上述值将破坏查询,删除表并注释掉(-- 在 SQL 中是注释)剩余的查询代码。
处理这种情况的一种方法是防止查询被破坏。只要查询是有效的,即使没有找到匹配的数据,数据库也不会暴露。
我创建了一个新的变量,代码将用数据填充它!由于 ASP.NET Web Pages 不允许在查询中使用参数化,因此该变量用数据填充并传递。
var query = "%" +Request.Form["input"] + "%"; var selectTitleQuery = "SELECT * FROM Content WHERE PostTitle LIKE @0"; var selectContentQuery = "SELECT * FROM Content WHERE PostContent LIKE @0";
上面的代码完成了这项工作。
关注点
我今天学到了一件新东西,那就是我可以将 IEnumerable 转换为 List 对象,方法是将 IEnumberable 中的每个对象添加到 List 对象中!第二件我学到的事情是,不一定总是在 List 对象中使用 Class,您可以使用任何数据类型,因为它是一个泛型数据类型对象。
还有一件事,我学到的是 @ 运算符的用法,我以前就知道,但我有点忘记了,所以今天我学到了。您不能在 @ 里面使用 @。
历史
第一篇文章。