用于查询多个数据库的存储库模式
本文关键字:存储 模式 数据库 查询 用于 | 更新日期: 2023-09-27 18:37:05
这是一个非常奇怪的架构。请耐心等待。
我们有一个现有的分层应用程序(数据、逻辑/服务、客户端)。最新的要求是服务层应访问两个数据源!!!(别无他法)这两个数据源具有相同的数据库架构。
与大多数分层体系结构一样,我们有如下读取和写入方法:
IEnumerable<Product> GetAllProducts(),
Product GetProductById(ProductKey id),
IEnumerable<Product> FindProductsByName(string name)
产品 DTO 是:
class Product
{
public ProductKey Key { get; set;}
...
}
class ProductKey
{
public long ID { get; }
}
我们将范围缩小到两个可能的解决方案:
备选方案1:在读取方法中添加一个参数,以便服务知道要使用哪个数据库,如下所示:Product GetProductById(ProductKey ID, DataSource dataSource) DataSource
是一个枚举。
备选方案2(我的解决方案):将"数据源"属性添加到键类。这将在检索对象时由实体框架设置。此外,这不会持久化到数据库中。
class ProductKey
{
public long ID { get; }
public DataSource Source { get; } //enum
}
优点是更改对客户端的影响最小。
但是,人们不喜欢这个解决方案,因为
DataSource
不会增加业务价值。(我的回答是ID
也不会增加商业价值。它是一个代理键。其目的是跟踪持久性)- 对象图中的子项还将包含冗余
DataSource
哪种解决方案更合理?您还有其他选择吗?
注意:这些服务无处不在。
我建议的是3号门:
[||||||||||||||]
[|||||||||s! ]
[||||nerics! ]
[ Generics! ]
我使用"动态存储库"(或者至少我是这样称呼它的)。它被设置为能够连接到任何数据上下文或数据库集,同时仍然处于相同的使用块中(即无需重新实例化)。
以下是我如何使用它的片段:
using (var dr = new DynamicRepo())
{
dr.Add<House>(model.House);
foreach (var rs in model.Rooms)
{
rs.HouseId = model.House.HouseId;
dr.Add<Room>(rs);
}
}
这使用定义的"默认"数据库上下文。每个都必须在存储库中定义,但不能实例化。这是我使用的构造函数:
public DynamicRepo(bool Main = true, bool Archive = false)
{
if (Main)
{
this.context = new MainDbContext();
}
if (Archive)
{
this.context = new ArchiveDbContext();
}
}
这是一个简化版本,其中只有两个上下文。可以实现更深入的选择方法来选择要使用的上下文。
然后一旦初始化,Add 的工作原理如下:
public void Add<T>(T te) where T : class
{
DbSet<T> dbSet = context.Set<T>();
dbSet.Add(te);
context.SaveChanges();
}
这样做的一个很好的优点是只有一个位置来维护与数据库交互的代码。所有其他逻辑都可以抽象成不同的类。以这种方式使用通用存储库肯定为我节省了大量时间 - 即使我一开始花了一些时间修改它。
我希望我没有误解您在寻找的内容,但是如果您尝试为多个数据源提供一个存储库,我相信这是一个很好的方法。