使用 ASP.Net 核心连接到 2 个不同的 MartenDB 数据存储
Connect to 2 different MartenDB datastores with ASP.Net Core
在 ASP.Net Core 中设置 MartenDB 数据存储时,通常将这样的代码放在 Startup.cs:
services.AddMarten(o =>
{
o.Connection(configuration.GetConnectionString("MyDatabase"));
o.AutoCreateSchemaObjects = AutoCreate.All;
o.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });
});
这允许您随后将 IDocumentSession 和 IDocumentStore 注入您的各种 类 以使用该数据库。
现在,如果您必须连接到第二个数据库,您会怎么做?我查看了 ISessionFactory 但显然您无法从此处更改连接字符串。您需要手动创建和注册新的 DocumentStore 吗?
为了回答我自己的问题,我最终为每个我想连接的数据库创建了一个自定义的 DocumentStore 和 ISessionFactory,然后注入了自定义的 SessionFactory。
这是代码(为简洁起见,仅显示每个 class 的一个实例。只需将 Db1
替换为 Db2
每个 class 的第二个版本):
自定义 DocumentStore:
public class Db1Store : DocumentStore
{
public Db1Store(StoreOptions options) : base(options)
{
}
}
自定义SessionFactory:
public class Db1SessionFactory : ISessionFactory
{
private readonly Db1Store store;
public Db1SessionFactory(Db1Store store)
{
this.store = store;
}
public IQuerySession QuerySession()
{
return store.QuerySession();
}
public IDocumentSession OpenSession()
{
return store.OpenSession();
}
}
服务注册(这取代了 services.AddMarten
调用):
services.AddSingleton(p =>
{
var options = new StoreOptions();
options.Connection(configuration.GetConnectionString("DB1"));
options.AutoCreateSchemaObjects = AutoCreate.All;
options.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });
return new Db1Store(options);
});
services.AddSingleton<Db1SessionFactory>();
然后将 Db1SessionFactory 实例注入 class,然后 运行 查询如下:
var result = await db1SessionFactory.QuerySession().Query<MyAwesomeTable>().ToListAsync();
缺点:
我更愿意注入 QuerySession 或 DocumentSession,但如果不移动到 Autofac 或支持命名实例的类似 DI 容器,我看不出有什么方法可以做到这一点。
我不确定以这种方式创建这些 QuerySession/DocumentSessions 会有什么缺点。这可能是一个糟糕的权衡。
在 ASP.Net Core 中设置 MartenDB 数据存储时,通常将这样的代码放在 Startup.cs:
services.AddMarten(o =>
{
o.Connection(configuration.GetConnectionString("MyDatabase"));
o.AutoCreateSchemaObjects = AutoCreate.All;
o.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });
});
这允许您随后将 IDocumentSession 和 IDocumentStore 注入您的各种 类 以使用该数据库。
现在,如果您必须连接到第二个数据库,您会怎么做?我查看了 ISessionFactory 但显然您无法从此处更改连接字符串。您需要手动创建和注册新的 DocumentStore 吗?
为了回答我自己的问题,我最终为每个我想连接的数据库创建了一个自定义的 DocumentStore 和 ISessionFactory,然后注入了自定义的 SessionFactory。
这是代码(为简洁起见,仅显示每个 class 的一个实例。只需将 Db1
替换为 Db2
每个 class 的第二个版本):
自定义 DocumentStore:
public class Db1Store : DocumentStore
{
public Db1Store(StoreOptions options) : base(options)
{
}
}
自定义SessionFactory:
public class Db1SessionFactory : ISessionFactory
{
private readonly Db1Store store;
public Db1SessionFactory(Db1Store store)
{
this.store = store;
}
public IQuerySession QuerySession()
{
return store.QuerySession();
}
public IDocumentSession OpenSession()
{
return store.OpenSession();
}
}
服务注册(这取代了 services.AddMarten
调用):
services.AddSingleton(p =>
{
var options = new StoreOptions();
options.Connection(configuration.GetConnectionString("DB1"));
options.AutoCreateSchemaObjects = AutoCreate.All;
options.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });
return new Db1Store(options);
});
services.AddSingleton<Db1SessionFactory>();
然后将 Db1SessionFactory 实例注入 class,然后 运行 查询如下:
var result = await db1SessionFactory.QuerySession().Query<MyAwesomeTable>().ToListAsync();
缺点:
我更愿意注入 QuerySession 或 DocumentSession,但如果不移动到 Autofac 或支持命名实例的类似 DI 容器,我看不出有什么方法可以做到这一点。
我不确定以这种方式创建这些 QuerySession/DocumentSessions 会有什么缺点。这可能是一个糟糕的权衡。