这是一个非常奇怪的架构。请耐心等待。
我们有一个现有的分层应用程序(数据,逻辑/服务,客户端)。 最新的要求是服务层应该访问两个数据源! (别无他法) 这两个数据源具有相同的DB模式。
与大多数分层体系结构一样,我们有读写方法,如:
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:
在read方法中添加一个参数,以便服务知道要使用哪个DB,如下所示:
产品GetProductById(ProductKey id,DataSource dataSource)
DataSource
是一个枚举。
备选方案2(我的解决方案): 将DataSource属性添加到键类。这将在检索对象时由Entity Framework设置。此外,这不会持久存储在数据库中。
class ProductKey
{
public long ID { get; }
public DataSource Source { get; } //enum
}
优点是更改对客户的影响最小。
然而,人们不喜欢这个解决方案,因为
DataSource
不会增加商业价值。 (我的回答是这样的
ID
也不会增加业务价值。它是一个代理键。它的
目的是跟踪持久性)DataSource
哪种解决方案更健全?你有其他选择吗?
注意:这些服务随处可用。
答案 0 :(得分:4)
我建议的是门号3:
[||||||||||||||]
[|||||||||s! ]
[||||nerics! ]
[ Generics! ]
我使用“动态存储库”(或者至少就是我所说的)。它被设置为能够连接到任何datacontext或dbset,同时仍然在相同的使用块中(即没有重新实例化)。
以下是我如何使用它的摘录:
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);
}
}
这使用定义的“默认”dbcontext。每个必须在存储库中定义,但不实例化。这是我使用的构造函数:
public DynamicRepo(bool Main = true, bool Archive = false)
{
if (Main)
{
this.context = new MainDbContext();
}
if (Archive)
{
this.context = new ArchiveDbContext();
}
}
这是一个简化版本,只有两个上下文。可以实现更深入的选择方法以选择要使用的上下文。
然后一旦初始化,这将是添加工作的方式:
public void Add<T>(T te) where T : class
{
DbSet<T> dbSet = context.Set<T>();
dbSet.Add(te);
context.SaveChanges();
}
这样做的一个很好的优点是,只有一个位置可以维护与数据库交互的代码。所有其他逻辑可以被抽象为不同的类。它确实为我节省了大量时间以这种方式使用通用存储库 - 即使我最初花了一些时间修改它。
我希望我没有误解你在寻找什么,但如果你想为多个数据源建立一个存储库,我相信这是一个很好的方法。