用于查询多个数据库的存储库模式

时间:2012-06-13 10:55:23

标签: c# entity-framework nhibernate architecture n-tier-architecture

这是一个非常奇怪的架构。请耐心等待。

我们有一个现有的分层应用程序(数据,逻辑/服务,客户端)。 最新的要求是服务层应该访问两个数据源! (别无他法) 这两个数据源具有相同的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

哪种解决方案更健全?你有其他选择吗?

注意:这些服务随处可用。

1 个答案:

答案 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();
    }

这样做的一个很好的优点是,只有一个位置可以维护与数据库交互的代码。所有其他逻辑可以被抽象为不同的类。它确实为我节省了大量时间以这种方式使用通用存储库 - 即使我最初花了一些时间修改它。

我希望我没有误解你在寻找什么,但如果你想为多个数据源建立一个存储库,我相信这是一个很好的方法。