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

在MVC 5中嵌入RavenDb

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.28/5 (8投票s)

2014 年 11 月 25 日

CPOL

4分钟阅读

viewsIcon

34687

基本上,这是一个使用 RavenDb 设置工作 MVC 项目的逐步指南。当然,它并非旨在展示任何使用 RavenDb 的最佳实践或任何架构设计。

引言

如果您已经阅读或以嵌入方式使用过 RavenDb,那么这篇文章不适合您。我发布它的主要原因是我想与您分享我在使用 Nuget 和 RavenDb 客户端时遇到的多个问题。我也想分享我解决它们的方式。

基本上,这是一个使用 RavenDb 设置工作 MVC 项目的逐步指南。当然,它并非旨在展示任何使用 RavenDb 的最佳实践或任何架构设计。

RavenDb 作为一个 NoSql 数据库,使其轻巧易用,就像 MongoDb 或 Redis 一样。我已经写过关于它们的 How-Tos。您可以在这里查看它们

那么,让我们从 RavenDb 开始吧

  • 打开 Visual Studio 2013 并添加一个 MVC 5 项目。
  • 打开 nuget 管理器控制台并键入 Install-Package RavenDB.Embedded 以安装可嵌入的客户端。在某些 Nuget 版本中,您可能会遇到类似的问题。

我遇到了以下错误

将 'System.Spatial 5.2.0' 更新为 'System.Spatial 5.0.2' 失败。无法找到与 'System.Spatial 5.0.2' 兼容的 'RavenDB.Database' 版本。

似乎试图以相反的方向更新 system.special 包:从 System.Spatial 5.2.0System.Spatial 5.0.2。要解决此 Nuget 问题,请强制 Nuget 在最高版本上运行。因此,重新输入先前的安装命令如下

Install-Package RavenDB.Embedded -DependencyVersion Highest
using Raven.Client;
public class RavenDbConfig
{
    private static IDocumentStore _store;
    public static IDocumentStore Store
    {
        get
        {
            if (_store == null)
                throw new InvalidOperationException(
                "IDocumentStore has not been initialized.");
            return _store;
        }
    }

    public static IDocumentStore Initialize()
    {
        _store = new EmbeddableDocumentStore 
        { 
            ConnectionStringName = "RavenDB" 
        };
        _store.Conventions.IdentityPartsSeparator = "-";
        _store.Initialize();
        IndexCreation.CreateIndexes(Assembly.GetCallingAssembly(), Store);
        return _store;
    }
}

我不会在这里详细介绍每一行(前面的代码片段来自 Ayende 在 RavenDb 网站上的示例),但基本上,它会根据您的连接字符串初始化 EmbeddableDocumentStore。此对象将允许您访问文档存储。连接字符串通常位于 webconfig 文件中

<add name="RavenDB" connectionString="DataDir = ~\App_Data\Database" />

可能一开始很难看出来,但到目前为止,您已经拥有了开始编写 Ravendb 代码所需的一切。但是,根据您为某些 DLL 安装的版本,您可能会遇到一些关于编译的问题。让我们看看我遇到的问题以及如何解决它们

  1. 第一个错误是 newtonsoft.json。就像是
    Could not load file or assembly 'Newtonsoft.Json, Version=4.5.0.0,
        Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies

    为了解决这个问题,我在程序包管理器控制台中运行了这些命令

    uninstall-package newtonsoft.json -force
        install-package newtonsoft.json -version 4.5.11

    这看起来很粗暴,但它确实奏效了。

  2. 我遇到的另一个错误是

    该对象尚未初始化。确保在应用程序的启动代码中,在所有其他初始化代码之后调用 HttpConfiguration.EnsureInitialized()

    为了解决这个问题,我在 Global.asax 中添加了以下内容

    GlobalConfiguration.Configuration.EnsureInitialized();

到目前为止,我认为我们解决了项目中可能发生的编译问题。那么,让我们继续下一步

添加一个基础控制器

public class M2aBaseController : Controller 
{
    public IDocumentSession DocumentSession { get; set; }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.IsChildAction)
            return;
        this.DocumentSession = RavenDbConfig.Store.OpenSession();
        base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.IsChildAction)
            return;
        if (this.DocumentSession != null && filterContext.Exception == null)
            this.DocumentSession.SaveChanges();
            this.DocumentSession.Dispose();
            base.OnActionExecuted(filterContext);
    }
}

基本上,之前的 M2aBaseController 将负责 DocumentSession,并确保它在继承基础 Controller 的任何控制器操作之前打开并在之后立即被处理。这是由 RavenDb 的联合创始人 Ayende 在 RavenDb 网站上建议的。

这对于简单的应用程序来说非常棒,但是对于繁重的应用程序,我会将所有代码移动到它所属的数据层中的 M2aBaseControllerM2aBaseController 将成为 Repository 模式场景中的基本存储库。

除了应用程序的设计以及您选择在哪个层处理什么之外,使用 RavenDb 的价值仍然是一样的:易于使用,可靠,并且随附的客户端是幕后起作用的那个。

要将对象添加到数据存储区并从中取回数据,您的控制器应该继承自 M2aBaseController。然后,要创建一个文档,请添加一个 create 操作方法,如下所示

[HttpPost]        
public ActionResult Create()
{
    var schedule = new Schedule
    {
        Name=” Tirezzaf”,
        Description = "Ad asegh ar tmurt iyi d-jjan imezwura",
        Departure= DateTime.Today.AddDays(2)
    };
    this.DocumentSession.Store(schedule);

    return RedirectToAction(“Index”);
}

Schedule 是一个业务对象,我需要做的就是保存它:this.DocumentSession.Store(schedule);

我的 Schedule 现在就在数据存储区中(在数据库中,正如关系数据库人员会争论的那样)。这太容易了。

要取回文档并将它们发送到视图以供显示,请添加到您的 Index 方法(或其他方法)

 var schedules = this.DocumentSession.Query<Schedule>().OrderByDescending
(i => i.Name).ToList();

如您所见,这只是一个常规的 Linq 功能,用于对特定文档进行排序或搜索。我想您已经明白了,因此您可以稍微试用一下,以便习惯它。

当然,关于 RavenDb,您还可以发现很多东西,例如索引、分片以及如何通过浏览器管理您的存储区等。服务器版本也值得一试。在 RavenDb 网站上提供了大量信息、How-Tos 和其他文档。Ayende 在那里回答问题。

© . All rights reserved.