I am trying to figure out how to convert a Linq Expression between two types: One in my Business Repository and its related one in the Domain Repository. Both types have the same data properties that will be used in the queries. In my business layer, I have the following method that will perform a query based on a business entity:
BUSINESS REPOSITORY: Domain entities converted to business entities
public IQueryable<CustomerVendorProduct> Query(Expression<Func<CustomerVendorProduct,bool>> filterInBusinessRepo)
So, a consumer could do something like the following:
var list = BusinessRepository.Query(c => c.CustomerId == 77);
They would get a list of CustomerVendorProduct business objects with CustomerId == 77.
Within the Query() method of the Business Repository, I need to invoke the following method in the Domain Repository. It will retrieve the raw, encrypted domain entities from the database. Note that its query requires the entity type used in the Domain Repository. It is related to our business entity, but simply is involved in CRUD operations.
DOMAIN REPOSITORY: Raw, encrypted entities from the database
public IQueryable<CustomerVendorProductEntity> Query(Expression<Func<CustomerVendorProductEntity, bool>> filter)
So, the Query() method in the Business Repository would do something like the following:
var domainList = DomainRepository.Query(filterInBusinessRepo);
The result would be a list of CustomerVendorProductEntity objects. The business repository then translates them into CustomerVendorBusiness entities and returns them to the caller.
So, my question is how can I convert the Linq Expression from the Business Repository Entity Type: CustomerVendorProduct to the Domain Repository Entity Type: CustomerVendorProductEntity? I think that I must create a conversion method... Something like the following... But, I am lost as to how to effect the conversion. I would really appreciate your help:
// Convert the Linq Expression from our Business Layer to our Domain Layer.
private Expression<Func<CustomerVendorProductEntity, bool>> CVPToCVPE(Expression<Func<CustomerVendorProduct, bool>> filter)
{
var parms = System.Linq.Expressions.Expression.Parameter(typeof(CustomerVendorProductEntity), "destination");
var result = System.Linq.Expressions.Expression.Lambda<Func<CustomerVendorProductEntity, bool>>(filter, parms);
return result;
}
Thank you for your time and suggestions! Mike
11/02/2012: Wow, no replies? I would have thought that a lot of other developers have encountered this issue, especially within an MVC application... Still hoping for help...
Translating expression tree from a type to another type with complex mappings
This is an answer to a very similar question that I helped a guy with. Check it out and let me know if this doesn't meet your needs.
A MVC app that I developed a while back I did something like this but there was only a single set of entity objects (ie. the business layer used the same entities as the ORM). It worked pretty well (Line of Business app with just basic CRUD capabilities) although it was a little confusing with all of the expressions being passed around.
In your case I think you're going to be stuck traversing the business repository expression tree and recreating it with the domain repository objects, as you've alluded to in your convert code. I can't give any suggestions on this other than it's probably not going to be simple to implement or completely verify.
From what I've seen most of the time in 'real' MVC applications expressions are not passed between the layers and a standard API is used instead to pass what will be eventually built into a query in the data layer.