MongoDb和实体框架的抽象

jan*_*ann 5 c# abstraction entity-framework dependency-injection mongodb

由于Mark Seemann的引用,我可能无法完成任务:

如果您有一个特定的ORM,那么请明确它.不要将其隐藏在界面后面.它会产生一种幻觉,即您可以将一种实现替换为另一种实现.在实践中,这是不可能的.

但我想要完成的是通过改变我在启动时的依赖关系来切换我的实体框架ORM与MongoDb驱动程序.

但是我一直遇到问题,我没有提供足够的灵活性,或者只是new NotImplementedException();在我的MongoDb实现中有太多的问题.

我的接口当前结构如下所示:

public interface IReadEntities
{
    IQueryable<TEntity> Query<TEntity>() where TEntity : Entity;
}

public interface IWriteEntities : IUnitOfWork, IReadEntities
{
    TEntity Get<TEntity>(object firstKeyValue, params object[] otherKeyValues) where TEntity : Entity;

    Task<TEntity> GetAsync<TEntity>(object firstKeyValue, params object[] otherKeyValues) where TEntity : Entity;

    IQueryable<TEntity> Get<TEntity>() where TEntity : Entity;

    void Create<TEntity>(TEntity entity) where TEntity : Entity;

    void Delete<TEntity>(TEntity entity) where TEntity : Entity;

    void Update<TEntity>(TEntity entity) where TEntity : Entity;
}

public interface IUnitOfWork
{
    int SaveChanges();

    Task<int> SaveChangesAsync();

    Task DiscardChangesAsync();

    void DiscardChanges();

    void Reload<TEntity>(TEntity entity) where TEntity : Entity;

    Task ReloadAsync<TEntity>(TEntity entity) where TEntity : Entity;
}
Run Code Online (Sandbox Code Playgroud)

但是已经通过这个实现我不能做"完整的"MongoDb实现,因为MongoDb不使用工作单元模式或两阶段提交.

然后我想到了移动IUnitOfWork到扩展方法IWriteEntities,但后来我松开了我DbContext的连接到实体框架实现,我不会在静态方法中使用服务定位器模式.

所以我的最后一招,是问我有没有尝试过的黄金道路?或者我应该简单地创建另外两个接口:

public interface IEntityFrameworkWriter : IWriteEntities, IUnitOfWork {} // Move IUnitOfWork out of IWriteEntities

public interface IMongoDbWriter : IWriteEntities {}
Run Code Online (Sandbox Code Playgroud)

并在我的应用程序中使用它们.但话说回来,这不是我的计划.任何反馈都表示赞赏.

头探索

mne*_*syn 7

只需在启动时更改我的依赖项,就可以使用MongoDb驱动程序切换我的实体框架ORM.

这比接口的单纯问题要深刻得多.这将导致哲学的灾难性冲突.

MongoDB应该使用一些写重,通常是非规范化的数据结构.您的索引,插入和工作人员很复杂,查询很简单.必须仔细设计架构以支持您需要的查询,而不是基于对象之间的关系.

经典的SQL方法是相反的:单独的关系就足以提出一个好的数据结构,模式很简单(尽管很大)没有工人可以实现最终的一致性,但是查询非常复杂,通常是因为属于一起的东西必须分成两个或三个表.这就是为什么事务和工作单元是典型SQL环境中的关键,而MongoDB甚至不支持它们.

当然,我正在简化:这里有一个频谱,你可以滥用MongoDB和RDBMSes作为简单的键值存储; 你可以在SQL中提出一个非规范化的数据结构,你可以在MongoDB中保持大量的关系.但是你的MongoDB不会学习参照完整性或(分布式)事务,你的SQL Server也不会放弃SQL.

但是你使用的抽象越多,它们拥有更广泛的支持,你就会越多地隐藏这些臃肿的代码背后的关键原则.我认为通常可以说:足够抽象的界面可以通过任何技术实现,但它会让用户感到沮丧.

  • 美丽的答案.如果您正在讨论将MongoDB实现隐藏在您自己的接口之后,以便稍后您可以通过切换适配器将其替换为另一个NoSQL数据库,同时保持相同的查询原则,我会完全理解,但隐藏您的MongoDB调用背后的典型关系界面会给你和你的用户带来很多痛苦,会引入很多很多错误,并且可能会迫使你以一种从未打算使用的方式使用你的MongoDB,并可能会引入性能和可用性限制. (3认同)