在模型和 DTO 之间转换 LINQ 表达式以用于存储库和 DAO

Convert LINQ expressions between model and DTO for use in repositories and DAO

我正在尝试抽象出应用程序中的数据访问层和 repository/model 层。

到目前为止,我的架构使得我有我的存储库 returning 和接受我的模型 classes。

示例:车辆模型由 VehicleRepository 存储库管理。

现在,为了从实际模型中抽象出数据库层特定类型,我实现了 DAO 对象,并实现了 DTO。

示例:VehicleDao 将只接受和 return VehicleDto 对象(其属性与 Vehicle 模型略有不同,以说明数据库的特定类型)。 VehicleRepository 的工作是将 Vehicle 模型转换为 VehicleDto 并再次转换回来。

我的问题是何时要通过 LINQ 表达式发送。我的存储库将只接受基于车辆模型 class:

的表达式
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 对象有一个类似的方法,但它接受并 returns 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 > DTO 的转换移动到 DAO 对象中吗?我是否应该不使用表达式从 MongoDB 集合中查询数据,而是使用具体的函数,如 GetByName、GetByMake 等,而不是能够在方法中指定查询。

我的最终目标是让 model/repo 层与 DAO 层完全隔离。 1) 测试目的很明显,但是 2) 如果我需要从 MongoDB 转移到轨道上的其他地方,我只需要 rewrite/test 数据访问层。

任何解决这个问题的帮助都会很棒!

如果您尝试抽象层,那么您必须使用抽象。

我首先想到的是将您的函数基于接口而不是具体类型:

public interface IVehicleDomain  : IDomain   //you could extend a base interface if you wanted.
{
   public string Field1 { get; set; }
}

然后在您的域和 dto 类 之间实现此接口。最后在两个架构层上使用接口,接口应该存在于 dto 和域 类 都可以访问的公共程序集中。

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