如何在数据层或类中使用RavenDB查询?

时间:2021-05-14 15:49:02

I have setup RavenDB embedded in my MVC application. I follower all the tutorials to make the RavenController and I can query the Session in the controller.

我在MVC应用程序中安装了RavenDB。我关注所有的教程来创建RavenController,我可以在控制器中查询会话。

Now I would really like to break away from mixing data in the controller and create a Data layer so that I can do some Business logic which will help me create complex View Models.

现在,我真的想放弃在控制器中混合数据,创建一个数据层,这样我就可以做一些业务逻辑来帮助我创建复杂的视图模型。

How do I query the Session in a plain class file? I can't seem to find any info on how to do this.

如何在普通类文件中查询会话?我似乎找不到怎么做这件事的任何信息。

2 个解决方案

#1


2  

Dependency Injection is great for this. You move aside the creation of the necessary services and let the container manage the lifecycle of the components, including scoping IDocumentSession to one instance per HTTP request.

依赖注入是很好的。将必要服务的创建放在一边,让容器管理组件的生命周期,包括每个HTTP请求将IDocumentSession限定为一个实例。

As an example, using Autofac (you'd need both the Autofac and Autofac.Mvc5 packages) you could have a class in your App_Start folder like this, and then call AutofacConfig.Configure() from your Global.asax:

例如,使用Autofac(您需要Autofac和Autofac。您可以在App_Start文件夹中有这样的一个类,然后调用AutofacConfig.Configure()从您的Global.asax:

public static class AutofacConfig
{
    public static IContainer Container { get; private set; }

    public static void Configure()
    {
        var builder = new ContainerBuilder();
        var thisAssembly = Assembly.GetExecutingAssembly();

        // Register our controllers with the container
        builder.RegisterControllers(thisAssembly).PropertiesAutowired(PropertyWiringOptions.PreserveSetValues);

        // Provide injections of the HTTP abstractions (HttpContextBase, etc.)
        builder.RegisterModule(new AutofacWebTypesModule());

        // Create and register the Raven IDocumentStore
        builder.Register(c =>
        {
            var store = new DocumentStore {ConnectionStringName = "RavenDB"};
            store.Initialize();

            Raven.Client.Indexes.IndexCreation.CreateIndexes(typeof (MvcApplication).Assembly, store);

            return store;
        })
            .As<IDocumentStore>()
            .SingleInstance();

        // Provide injection of Raven IDocumentSession
        builder.Register(c => c.Resolve<IDocumentStore>().OpenSession())
            .InstancePerRequest();

        Container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));
    }
}

Then, when you need an IDocumentSession some place outside of a controller:

然后,当你需要一个IDocumentSession在控制器外的某个地方:

// Business logic, or other class that injection is not provided for.
var session = AutofacConfig.Container.Resolve<IDocumentSession>();

Also include autofac otherwise you will get an error saying "does not contain definition Resolve ..."

还包括autofac,否则你会得到一个错误,说“不包含定义解析……”

using Autofac;

You can do similar things with most other DI container libraries; the API is just slightly different.

您可以对大多数其他DI容器库执行类似的操作;API只是略有不同。

#2


0  

HttpContext.Current.Session holds current session, but you should definitely not use it in business logic layer. Business logic layer should not be aware of HttpContext.

HttpContext.Current。会话保存当前会话,但是您绝对不应该在业务逻辑层中使用它。业务逻辑层不应该知道HttpContext。

Basic solution to this problem would be to create interface:

解决这个问题的基本方法是创建接口:

public interface ISession 
{
    int SomeValue { get; set; }
}

and implementation

和实现

public class HttpContextBasedSession : ISession 
{
    public int SomeValue
    {
        get
        {
            return Convert.ToInt32(HttpContext.Current.Session["SomeValue"]);
        }

        set
        {
            HttpContext.Current.Session["SomeValue"] = value;
        }
    }
}

Bind it with dependency injection framework.

用依赖注入框架绑定它。

#1


2  

Dependency Injection is great for this. You move aside the creation of the necessary services and let the container manage the lifecycle of the components, including scoping IDocumentSession to one instance per HTTP request.

依赖注入是很好的。将必要服务的创建放在一边,让容器管理组件的生命周期,包括每个HTTP请求将IDocumentSession限定为一个实例。

As an example, using Autofac (you'd need both the Autofac and Autofac.Mvc5 packages) you could have a class in your App_Start folder like this, and then call AutofacConfig.Configure() from your Global.asax:

例如,使用Autofac(您需要Autofac和Autofac。您可以在App_Start文件夹中有这样的一个类,然后调用AutofacConfig.Configure()从您的Global.asax:

public static class AutofacConfig
{
    public static IContainer Container { get; private set; }

    public static void Configure()
    {
        var builder = new ContainerBuilder();
        var thisAssembly = Assembly.GetExecutingAssembly();

        // Register our controllers with the container
        builder.RegisterControllers(thisAssembly).PropertiesAutowired(PropertyWiringOptions.PreserveSetValues);

        // Provide injections of the HTTP abstractions (HttpContextBase, etc.)
        builder.RegisterModule(new AutofacWebTypesModule());

        // Create and register the Raven IDocumentStore
        builder.Register(c =>
        {
            var store = new DocumentStore {ConnectionStringName = "RavenDB"};
            store.Initialize();

            Raven.Client.Indexes.IndexCreation.CreateIndexes(typeof (MvcApplication).Assembly, store);

            return store;
        })
            .As<IDocumentStore>()
            .SingleInstance();

        // Provide injection of Raven IDocumentSession
        builder.Register(c => c.Resolve<IDocumentStore>().OpenSession())
            .InstancePerRequest();

        Container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));
    }
}

Then, when you need an IDocumentSession some place outside of a controller:

然后,当你需要一个IDocumentSession在控制器外的某个地方:

// Business logic, or other class that injection is not provided for.
var session = AutofacConfig.Container.Resolve<IDocumentSession>();

Also include autofac otherwise you will get an error saying "does not contain definition Resolve ..."

还包括autofac,否则你会得到一个错误,说“不包含定义解析……”

using Autofac;

You can do similar things with most other DI container libraries; the API is just slightly different.

您可以对大多数其他DI容器库执行类似的操作;API只是略有不同。

#2


0  

HttpContext.Current.Session holds current session, but you should definitely not use it in business logic layer. Business logic layer should not be aware of HttpContext.

HttpContext.Current。会话保存当前会话,但是您绝对不应该在业务逻辑层中使用它。业务逻辑层不应该知道HttpContext。

Basic solution to this problem would be to create interface:

解决这个问题的基本方法是创建接口:

public interface ISession 
{
    int SomeValue { get; set; }
}

and implementation

和实现

public class HttpContextBasedSession : ISession 
{
    public int SomeValue
    {
        get
        {
            return Convert.ToInt32(HttpContext.Current.Session["SomeValue"]);
        }

        set
        {
            HttpContext.Current.Session["SomeValue"] = value;
        }
    }
}

Bind it with dependency injection framework.

用依赖注入框架绑定它。