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

Northwind 数据库与 NoSQL DBreeze

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2014 年 7 月 23 日

CDDL

10分钟阅读

viewsIcon

25618

downloadIcon

552

在 SQL Northwind 数据库上使用 NoSQL DBreeze 数据库与 ASP.NET。

引言

这是一篇关于在 ASP.NET 中使用 NoSQL 的小文章(也是我的第一篇文章),发布在 CodeProject 上。NoSQL 已经存在很长时间了,许多人成功地使用了 NoSQL。我发现关于在 ASP.NET 中使用 NoSQL 的代码和完整示例非常少。每个 NoSQL 数据库都提供了插图和示例,但仅限于入门级别。因此,我将我的整个经过测试的项目作为一篇文章,献给那些对 NoSQL 感兴趣并具有 ASP.NET 背景的人。

可以在学习前下载整个源代码,但必须具备 ASP.NET、C#、Lambda 表达式、N-Tier、泛型、JQuery、JavaScript、KnockoutJs 和 CSS 的经验。当然,还必须使用过 SQL Server 并理解基本的 Northwind 数据库,这个数据库已经存在了 15 年。运行完整代码的唯一要求是 Visual Studio 2010 或更高版本。

背景

关于 NoSQL 的一点介绍。如果你是 NoSQL 的新手,那么 NoSQL 将与传统的 RDBMS 关系型数据库有所不同。所以,首先只需将其视为一个没有关系(意味着没有 RDBMS),因此没有连接约束的数据库。只有实体和一组内部(或依赖)实体,直接保存到磁盘或内存中可管理的文件。如果数据库在磁盘上,它可以直接位于同一工作项目、托管环境或云上。简单地说,有关详细信息,我建议在网上搜索 NoSQL。:-)

本文我将使用 DBreeze NoSQL 嵌入式数据库。如果你下载了源代码,你会发现 DBreeze 二进制文件已经包含在内。如果你想了解更多详细信息,可以直接在网上搜索 DBreeze 并访问他们的主页。

我想,背景介绍得差不多了,现在我们开始借助源代码详细讲解。

Using the Code

只需下载源代码并将其解压到系统上你喜欢的位置。在 Visual Studio 2010 或更高版本中打开项目。

运行前我们需要做一些小的设置,因此首先打开名为 "Site" 的网站的 web.config 文件。在配置文件开头搜索以下行。

<configSections> 
    <section name="logger" type="Logger.Configuration.LoggerConfiguration, Logger">
    <section name="dbreezedbconfig" type="DataLayer.DataBaseConfig.DBreezeConfiguration, DataLayer">
  <configSections>

  <logger name="mylogger">
    <logconfig folder="sitelog" file="log.txt" filesize="5" rollday="true"><logconfig>
  <logger>

  <dbreezedbconfig name="databaseconfig">
    <dbreezeconfig databasefolder="App_Data\northwind_db" usebackup="true" backupfolder="I:\NoSql\NorthWind" backupinterval="60"><dbreezeconfig>
  <dbreezedbconfig>

我简单解释一下,第一部分是日志记录器,这是我创建的自定义日志记录器,其详细信息在 configSections 下的 logger 标签中。

  1. “folder” 属性将是直接在网站根目录下创建的日志文件夹。
  2. “file” 属性是日志文件的名称。
  3. “filesize” 属性是日志文件的大小,这里是 5 GB。达到此大小后,会自动创建另一个文件。
  4. “rollday” 属性是每天更改文件的属性。

整个 Logger 代码包含在源代码中的“Logger”类库下。现在是第二个配置部分,这对于我们使用 DBreeze NoSQL 数据库很重要。详细信息如下:

  1. “databasefolder” 属性指定了我们的数据库将存储在哪里。通常我们将其保存在网站应用程序的 App_Data 文件夹中,因此这里也使用了相同的模式。
  2. “usebackup” 属性指定是否要自动备份 DBreeze 数据库。这里我们使用备份。
  3. “backupfolder” 属性指定备份需要保存在哪里。请注意,这应该是您系统上的物理位置或共享位置,并且必须赋予 IIS 指定的权限。如果我们在步骤 2 中指定使用备份,则此属性是必需的,否则当然会出错。如果指定的文件夹未找到,也会出错。
  4. “backupinterval” 属性指定何时进行下一次备份。该数字以分钟为单位,这里是 60,表示每小时需要进行一次备份。(请注意,DBreeze 会按照我们设置的间隔自动备份数据库。)就是这样,如果上述所有配置设置都正确,现在是编译解决方案的时候了,将启动项目设置为我们的网站应用程序,并将起始页设置为 index.html,在 Visual Studio 中按 F5,然后一切就绪了。

有人会想,当你第一次运行应用程序时,会发生什么?让我简单说明一下工作原理。

打开 Global.asax 文件

  1. 在 Application Start 事件中,有两行代码执行初始设置。
  2. 第一行调用 DBreeze 数据库引擎,当然在应用程序结束时会释放引擎。
  3. 第二行使用 DBreeze 创建 northwind 数据库,该数据库在 App_Data 文件夹中创建。只需转到 Business.BaseDataBase 类库,整个脚本都在那里编码。此脚本仅在未找到最需要的基础表时运行一次,这意味着我们是第一次运行。

数据库创建后,整个应用程序开始连接并与我们的数据库交互。请注意,由于我们使用的是嵌入式数据库,数据库的所有文件现在都被锁定。因此,我们每小时会创建一个备份,以便如果需要,我们可以复制实时数据库并开始调查。

关注点

整个解决方案包含工作项目。在详细介绍 NoSQL 之前,让我先阐明项目的基础结构以便于理解。打开解决方案,它将如下图所示。

  1. Business.Entities 类库包含所有实体。这将进一步用作 NoSQL 的表。NoSQL 没有像 SQL Server 中那样的表。
  2. DataLayer 类库包含我们的 DBreeze 数据库的存储库类以及使 Dbreeze 运行所需的其他配置元素。存储库用于查询数据库以获取相关数据。由于我们已经在 web.config 中完成了数据库配置,因此配置的基类位于 DataLayer 类库中。
  3. Business.Components 类库包含所有我们需要实现的业务逻辑。
  4. NWSTS 类库有一个简单的 Factory 类,这样我们就可以封装所有在另一端不需要的数据。
  5. Service 类库包含由我们的 Web 应用程序使用的 Web 服务。
  6. Logger 类库包含用于记录错误或任何其他信息的代码。
  7. Business.BaseDataBase 类库包含 NoSQL 脚本,该脚本仅在 northwind 数据库未创建时使用一次。

    在所有类库中,我们都必须引用 DBreeze DLL。

现在,让我们看看 DBreeze 提供了什么。以下是一些需要理解的要点:

  1. DBreeze 是一款 NoSQL 嵌入式数据库,它使用一个类作为表。我们在类中定义的任何属性都被视为表的列。
  2. DBreeze 易于维护数据库引擎以进行事务提交和回滚,因此操作是 ACID 类似的并且完全可管理。
  3. DBreeze 需要为数据库中每个表中的每一行提供一个唯一键。因此,传统上在 SQL Server 中我们有主键,DBreeze NoSQL 也是相同的概念。唯一的区别是我们需要 System.Collections.Generics.Dictionary 而不是 System.Collections.Generics.List。因此,主键可以保存在类中,也可以保存在 System.Collections.Generics.Dictionary 的键中。
  4. DBreeze NoSQL 引擎需要在应用程序的整个生命周期中启动一次,然后进行处置。因此,我们可以从 global.asax 文件启动它,或者我们可以为此编写自定义 Windows 服务,然后公开引擎。(我没有尝试过 Windows 服务,但由于我们可以在 .NET 中编写自定义 Windows 服务,因此这可以很容易实现。)
  5. DBreeze 提供事务,因此传统的提交和回滚使得它对于 SQL Server 用户非常熟悉。有一个简单的经验法则,如果在事务中数据未提交,数据将简单地保存在内存中。
  6. DBreeze 事务提供同步表功能,因此我们可以显式同步表。这使得与其他表交互的其他线程等待,直到第一个完成。
  7. DBreeze 事务还提供整个表的排他锁和共享锁。
  8. DBreeze 最吸引人的特性(我最喜欢)是它无需安装,即插即用,所有后续操作都是完全可管理且是 .NET 的托管代码。我们只需引用 DBreeze DLL 即可。

等等,也有一些缺点,让我们也考虑一下。

  1. 如上文第 3 点所述,我们需要为每一行设置一个键,而键可以是 .Net 中除 GUID 之外的任何有效数据类型。如果我们需要使用 GUID,这会使 GUID 覆盖 ToString()。
  2. 我们需要对 DBreeze 引擎采取预防措施,因为它只能初始化和处置一次。因此,我们要么需要一遍又一遍地打开引擎并使用 using 关键字同时处置,要么我们需要全局打开或关闭它。(后者在我们的源代码项目中使用)

请注意,我发现了以上几点,也许会有新的版本发布,或者我可能错过了一些要点。但它们都基于我对 DBreeze 的经验。

让我们看看 DBreeze NoSQL 插入和检索数据的基本用法

    using DBreeze;
    public class myClass
    {
	      public string id {get;set;}
	      public string name{get;set;}
    }
    myClass _myClass = new myClass(){id="1",name="name"};
    using (var engine =  new DBreezeEngine(@"D:\temp\DBR1"))
    {
          using (var tran = engine.GetTransaction()) 
          { 
            try 
            { 
                  tran.Insert<int, DbMJSON<myClass>>("t1", 1, _myClass);
                  tran.commit();
            } 
            catch (Exception ex) 
            { 
                  tran.rollback();
            }
    }
    using (var engine =  new DBreezeEngine(@"D:\temp\DBR1"))
    {
            using (var tran = engine.GetTransaction()) 
            { 
              try 
              { 
                myClass _myClass = Tran.SelectForward<int, DbMJSON<myClass>>("t1").Select(qr=>qr.Value.Get).Where(qr=>qr.name == "name").FirstOrDefault();
              }
              catch(Exception ex)
              {
	            //log error
              }
            }
}

如上所示,在表中插入和检索数据非常简单。但是更新呢?DBreeze 没有更新!不要感到惊讶,忘记 SQL Server 吧,这是 NoSQL。对于更新,使用相同的插入操作,如果主键已经在数据库中存在,则更新该记录,如果不存在,则插入。从而最大限度地减少错误。

上述代码在我们的项目中以存储库的形式实现,因此我们不必每次都记住表的结构。我们需要一些泛型经验(开头已说明),如果具备,DataLayer 类库就不需要进一步解释了。泛型仅用于支持上述代码,当然是以泛型的方式。此外,它还包含共享和排他场景的事务类型。我们可以根据业务逻辑需求使用。

我需要提及的最后一点是订单搜索功能。如果你运行应用程序,你会从主屏幕找到订单搜索,点击它并尝试搜索任何订单。你会发现搜索有点慢!为什么?因为我已经在 NoSQL 中实现了 SQL Server,这会产生差异,NoSQL 的结构不应与 SQL Server 的结构和架构相同。我创建这个项目是为了理解 SQL Server 和 NoSQL 之间架构差异。所以让我们简单谈谈这一点。

首先,在 SQL Server 中存在关系。如果熟悉 NorthWind 数据库,我们知道其中

  1. 订单依赖于订单详情、客户、员工和发货人。
  2. 此外,订单详情依赖于产品。
  3. 产品依赖于供应商和类别。

请在 NorthWind 数据库中验证这一点。因此,在创建订单和订单详情之前,我们需要客户、员工、发货人、供应商和产品。当然,依赖关系都在主表上。因此,只需要引用即可。

那么 NoSQL 场景会是怎样的呢?同样地,我们仍然需要主表,但这不再是强制约束。为什么?因为每一个细节都将只添加到 Orders 实体中。我们可以直接映射创建订单的员工、客户、产品,以及发货人和供应商!简单。我们不需要先完成主表再操作依赖表,我们只需当场创建主表并进行关联,即订单实体。

这就是为什么在我们的应用程序中订单搜索很慢的原因,我们坚持了 SQL Server 的架构,这样做是为了我们更好地理解。此外,在 OrderSearch (在 Buisness.Components.Components, 命名空间中) 中,大量使用了 Linq 表达式来创建动态 lambda 表达式。查看一下该类,是的,当然需要了解泛型、Linq 表达式和 Lambda。但在 NoSQL 架构中,情况并非如此。那会非常简单。

客户端还有一个额外的库是 KnockoutJs。它用于轻松地将实体列表与 HTML 和 CSS 绑定。如果你是 KnockoutJs 的新手,只需在 Knockout 官方网站上学习一个简短的教程即可。这些教程简单明了,易于实现。

我想这篇文章到此为止了。说了很多。我期待您对本文的评论,如果我有所遗漏或采用了其他实现方式,欢迎您的建议。此外,我对网页应用程序中实现的糟糕网页设计表示歉意。

谢谢。

© . All rights reserved.