我正在与工作单位一起实现存储库模式(Mongo db(。从存储库中添加/更新/删除实体只需更新实体状态中的内存(跟踪(列表,然后由其SaveChanges()
方法的工作单位使用该列表,以实际在数据库上执行CUD操作。
例如Repository.Add()
方法:
public void Add(TEntity entity)
{
TrackingList[entity] = new EntityData<TEntity>(entity, EntityState.Added);
}
然后,在工作单位SaveChanges()
实施中:
var addedEntities = repository.TrackingList.Values.Where(v => v.State == EntityState.Added).Select(v => v.Entity);
if (!addedEntities.Any())
return;
// inserts the added entities to the Mongo DB collection
repository.Collection.InsertMany(addedEntities);
在特定实体上明确执行CUD操作时,这起作用。然后我可以管理此跟踪列表。
但是现在我试图实现以下方法:
DeleteWhere(Expression<Func<Entity, bool>> filter);
问题是我无法跟踪更改的实体,因为我对将要通过过滤器的实体一无所知。
我也可能必须支持通过过滤器更新部分实体。
如果可能的话,正确的方法是什么?
我不知道实现 bulk delete(是否有条件(的ORM 和 bulk update(有条件是否有条件(功能完全尊重 uow。是的;许多ORM支持这些功能;但是在这种情况下,UOW并没有得到荣誉或部分荣誉。是的,数据库操作只会在Flushing上执行(如您所说,SaveChanges()
(;但是内存副本或内存状态将无法保证与基本RDBMS保持一致的状态。
有一个原因。为了使UOW工作,必须将实体加载到内存中。在上面的情况下,不能保证这一点。使这两个功能在UOW下起作用的唯一方法是将这些实体加载在背景中的内存中(如果尚未加载(,然后采取操作。这将非常低效。许多ORMS通过不尊重或部分园艺来提供这两个功能。
关于部分实体更新,您必须跟踪 properties (成员级(中的更改,而不仅仅是跟踪实体中的更改(类级(。
据我所知,有两种方法可以跟踪更改:
-
标志
您只需在内存中的每个实体实例上维护一些标志即可。如果对该特定实例采取任何措施,则相应地修改其相关标志。冲洗时,您只需检查此标志,并按照其状态采取CUD行动。您不能以这种方式跟踪成员级别的更改。
-
快照
以这种方式,ORM最初加载实体时将其副本维护。实际加载实体暴露于更改。在冲洗时,对原始副本进行了检查。通过这种方式,您可以检测会员级别的更改。记忆和其他整体管理成本在这里更高。