我正在尝试在我的应用程序中抽象出数据访问层和存储库/模型层。
到目前为止,我有我的架构,以便我的存储库返回并接受我的模型类。
示例:车辆模型由VehicleRepository仓库管理。
现在,为了从实际模型中抽象出数据库层特定类型,我实现了DAO对象,并实现了DTO。
示例:VehicleDao将仅接受并返回VehicleDto对象(其与Vehicle模型具有略微不同的属性以考虑特定于数据库的类型)。 VehicleRepository的工作是将Vehicle模型转换为VehicleDto并再次返回。
我的问题是当我想通过LINQ表达式发送时。我的存储库只接受基于Vehicle模型类的表达式:
public async Task<IList<Vehicle>> GetAll(Expression<Func<Vehicle, bool>> condition)
{
// Return the results
// _dao is type VehicleDao
return await _dao.Find<T>(condition);
}
我的DAO对象有一个类似的方法,但它接受并返回VehicleDto对象,并直接在数据库集合上工作。
public async Task<IList<VehicleDto>> GetAll(Expression<Func<VehicleDto, bool>> condition)
{
// Return the results
// _collection is my database managed collection (MongoDB in this case)
return await _collection.Find<T>(condition).ToListAsync();
}
显然,我遇到了构建错误,因为LINQ表达式在Vehicle和VehicleDto对象之间不兼容......
所以,我想知道解决这个问题的最佳方法是什么?我应该移动Model&gt;的转换吗? DTO进入DAO对象?我不应该使用表达式来查询MongoDB集合中的数据,并使用具体的函数,如GetByName,GetByMake等,而不是能够在方法中指定查询。
我的最终目标是让模型/ repo层与DAO层完全隔离。 1)显然测试目的,但2)如果我需要从MongoDB迁移到轨道上的其他东西,我只需要重写/测试数据访问层。
任何有关此问题的帮助都会很棒!
答案 0 :(得分:2)
如果您尝试抽象图层,则必须使用抽象。
将您的函数基于接口而不是具体类型将首先出现在我的脑海中:
public interface IVehicleDomain : IDomain //you could extend a base interface if you wanted.
{
public string Field1 { get; set; }
}
然后在您的域和dto类中实现此接口。最后在两个architecure层上使用接口,接口应该存在于dto和domain类都可以访问的公共程序集中。
public async Task<IList<Vehicle>> GetAll(Expression<Func<Vehicle, bool>> condition)
{
// Return the results
// _dao is type VehicleDao
return await _dao.Find<T>(condition);
}
public async Task<IList<IVehicle>> GetAll(Expression<Func<IVehicle, bool>> condition)
{
// Return the results
// _collection is my database managed collection (MongoDB in this case)
return await _collection.Find<T>(condition).ToListAsync();
}