1

这是一个非常奇怪的架构。请多多包涵。

我们有一个现有的分层应用程序(数据、逻辑/服务、客户端)。最新的要求是服务层要访问两个数据源!!!(没有其他办法)这两个数据源具有相同的数据库架构。

与大多数分层架构一样,我们有如下读写方法:

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(我的解决方案):将 DataSource 属性添加到键类。这将在检索对象时由实体框架设置。此外,这不会持久化到数据库中。

class ProductKey
{
    public long ID { get; }
    public DataSource Source { get; } //enum
}

优点是更改对客户的影响最小。

但是,人们不喜欢这种解决方案,因为

  • DataSource不会增加商业价值。(我的回答是它ID也不会增加商业价值。它是一个代理键。它的目的是跟踪持久性)
  • 对象图中的孩子也将包含DataSource哪些是冗余的

哪种解决方案更合理?你有其他选择吗?

注意:这些服务无处不在。

4

1 回答 1

4

我建议的是 3 号门:

[||||||||||||||]
[|||||||||s!   ]
[||||nerics!   ]
[  Generics!   ]

我使用“动态存储库”(或者至少这是我所说的)。它被设置为能够连接到任何数据上下文或数据库集,同时仍处于相同的 using 块中(即无需重新实例化)。

这是我如何使用它的片段:

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

这是一个简化版本,其中只有两个上下文。可以实施更深入的选择方法来选择要使用的上下文。

然后一旦初始化,这将是 Add 的工作方式:

    public void Add<T>(T te) where T : class
    {
        DbSet<T> dbSet = context.Set<T>();
        dbSet.Add(te);
        context.SaveChanges();
    }

这样做的一个很好的优点是只有一个地方来维护与数据库交互的代码。所有其他逻辑都可以抽象为不同的类。以这种方式使用通用存储库无疑为我节省了很多时间——即使我一开始花了一些时间修改它。

我希望我没有误解您要查找的内容,但是如果您尝试为多个数据源创建一个存储库,我相信这是一种好方法。

于 2012-06-13T23:20:07.553 回答