65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (11投票s)

2014年8月12日

CPOL

8分钟阅读

viewsIcon

67220

downloadIcon

769

本文介绍如何使用 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 表单,该表单从用户那里获取输入,如下所示,

HTML Form (Empty)

这是一个空表单,未填写任何值。填写以下值,看看会发生什么, 

HTML form (Software value)

此表单已填写了足够的信息,现在您可以继续单击“提交”按钮。这样做后,您将看到以下结果。 

“Software” - 结果页面您可以看到,结果已经出来了,其中至少包含一个“Software”一词的出现。其他已被排除在列表之外。只有相关内容会发布到网站上。还有一个结果显示包含“Software”一词的帖子的内容。因此,此网站会同时搜索标题和内容以获取查询。您可以编辑 UI,使其更适合您的应用程序,可以选择显示标题、内容或两者都显示,就像已经完成的一样!

现在让我们尝试另一个查询,为什么不试试特殊字符查询?尝试在查询框中输入“C#”,然后按搜索按钮,这次您将看到以下结果

“C#” - 结果这可能看起来与上一个相同,但实际上并非如此。您可以看到这次带有标题的帖子是一个新帖子,实际上是其他内容。因此,您可以看到代码每次都在数据库中搜索新数据,即它不使用缓存服务。它会持续搜索相关数据,并为您提供您正在寻找的准确查询,并丢弃您不想使用的其余项。

那么,如果我们数据库中没有的词呢?

嗯,这是此网站的另一项功能,它不会向您显示任何异常、错误或糟糕的用户体验。它会礼貌地告知您遇到的错误。它会告诉您输入的查询没有结果,就这么简单。 

您可以尝试在搜索框中输入“WebMatrix”并进行搜索,将会生成以下页面

"WebMatrix" - results

这将是 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,您可以使用任何数据类型,因为它是一个泛型数据类型对象。

还有一件事,我学到的是 @ 运算符的用法,我以前就知道,但我有点忘记了,所以今天我学到了。您不能在 @ 里面使用 @。 

历史

第一篇文章。

© . All rights reserved.