MongoDb 和 Entity Framework 的抽象
Abstraction over MongoDb and Entity Framework
由于 Mark Seemann 的这句话,我可能正在执行不可能的任务:
If you have a specific ORM in mind, then be explicit about it. Don't
hide it behind an interface. It creates the illusion that you can
replace one implementation with another. In practice, that's
impossible.
但我想要完成的是通过更改我对启动的依赖性来将我的 Entity Framework ORM 与 MongoDb 驱动程序切换出去。
但我一直 运行 遇到我没有提供足够的灵活性或在我的 MongoDb 实现中有太多 new NotImplementedException();
的问题。
我的接口当前结构如下所示:
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;
}
但是通过这个实现我已经不能做 "complete" MongoDb 实现,因为 MongoDb 不使用工作单元模式,或两阶段提交。
然后我想将 IUnitOfWork
移动到 IWriteEntities
的扩展方法中,但后来我松开了连接到 Entity Framework 实现的 DbContext
并且我不会在静态方法中使用服务定位器模式。
所以我最后的办法,就是问有没有什么黄金之路我还没有尝试过?或者我应该简单地再创建两个接口:
public interface IEntityFrameworkWriter : IWriteEntities, IUnitOfWork {} // Move IUnitOfWork out of IWriteEntities
public interface IMongoDbWriter : IWriteEntities {}
并在我的应用程序中使用这些。但话又说回来,这不是我的计划。感谢任何反馈。
爆头
switch my Entity Framework ORM out with the MongoDb driver just by changing my dependencies on startup.
这比 接口 的问题要深得多。这将导致哲学的灾难性冲突。
MongoDB 应该与写入量大、通常非规范化的数据结构一起使用。您的索引、插入和工作者很复杂,查询很简单。必须仔细设计架构以支持您需要的查询,而不是 基于对象之间的关系。
经典的SQL方法是相反的:仅凭关系就足以得出一个好的数据结构,模式很简单(尽管很大)没有最终一致性的工作者,但查询是非常复杂,通常是因为属于一起的东西必须拆分到两个或三个表中。这就是为什么事务和工作单元在典型的 SQL 环境中是关键,而在 MongoDB.
中甚至不支持它们。
当然,我正在简化:这里有一个范围,您可以滥用 MongoDB 和 RDBMS 作为简单的键值存储;你可以在 SQL 中想出一个非规范化的数据结构,你可以在 MongoDB 中保持大量的关系。但是您的 MongoDB 不会学习参照完整性或(分布式)事务并且您的 SQL 服务器不会放过 SQL.
但是你使用的抽象越多,它们得到的支持越广泛,你就越会把这些关键原则隐藏在一堆臃肿的代码后面。我想一般人可以说:一个足够抽象的接口可以用任何技术来实现,但它会让用户感到沮丧。
由于 Mark Seemann 的这句话,我可能正在执行不可能的任务:
If you have a specific ORM in mind, then be explicit about it. Don't hide it behind an interface. It creates the illusion that you can replace one implementation with another. In practice, that's impossible.
但我想要完成的是通过更改我对启动的依赖性来将我的 Entity Framework ORM 与 MongoDb 驱动程序切换出去。
但我一直 运行 遇到我没有提供足够的灵活性或在我的 MongoDb 实现中有太多 new NotImplementedException();
的问题。
我的接口当前结构如下所示:
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;
}
但是通过这个实现我已经不能做 "complete" MongoDb 实现,因为 MongoDb 不使用工作单元模式,或两阶段提交。
然后我想将 IUnitOfWork
移动到 IWriteEntities
的扩展方法中,但后来我松开了连接到 Entity Framework 实现的 DbContext
并且我不会在静态方法中使用服务定位器模式。
所以我最后的办法,就是问有没有什么黄金之路我还没有尝试过?或者我应该简单地再创建两个接口:
public interface IEntityFrameworkWriter : IWriteEntities, IUnitOfWork {} // Move IUnitOfWork out of IWriteEntities
public interface IMongoDbWriter : IWriteEntities {}
并在我的应用程序中使用这些。但话又说回来,这不是我的计划。感谢任何反馈。
爆头
switch my Entity Framework ORM out with the MongoDb driver just by changing my dependencies on startup.
这比 接口 的问题要深得多。这将导致哲学的灾难性冲突。
MongoDB 应该与写入量大、通常非规范化的数据结构一起使用。您的索引、插入和工作者很复杂,查询很简单。必须仔细设计架构以支持您需要的查询,而不是 基于对象之间的关系。
经典的SQL方法是相反的:仅凭关系就足以得出一个好的数据结构,模式很简单(尽管很大)没有最终一致性的工作者,但查询是非常复杂,通常是因为属于一起的东西必须拆分到两个或三个表中。这就是为什么事务和工作单元在典型的 SQL 环境中是关键,而在 MongoDB.
中甚至不支持它们。当然,我正在简化:这里有一个范围,您可以滥用 MongoDB 和 RDBMS 作为简单的键值存储;你可以在 SQL 中想出一个非规范化的数据结构,你可以在 MongoDB 中保持大量的关系。但是您的 MongoDB 不会学习参照完整性或(分布式)事务并且您的 SQL 服务器不会放过 SQL.
但是你使用的抽象越多,它们得到的支持越广泛,你就越会把这些关键原则隐藏在一堆臃肿的代码后面。我想一般人可以说:一个足够抽象的接口可以用任何技术来实现,但它会让用户感到沮丧。