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

时间:2015-07-21 00:22:41

标签: c# linq linq-expressions

我正在尝试在我的应用程序中抽象出数据访问层和存储库/模型层。

到目前为止,我有我的架构,以便我的存储库返回并接受我的模型类。

示例:车辆模型由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迁移到轨道上的其他东西,我只需要重写/测试数据访问层。

任何有关此问题的帮助都会很棒!

1 个答案:

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