I have a data layer which abstracts away the underlying implementation (Entity Framework) by accepting & returning models that are defined elsewhere. I want to be able to pass in a Func<T, bool>
predicate to one of the methods to allow additional clauses to be applied when querying the database.
Since the generic models know nothing of the underlying Entity Framework implementation, I need to convert my Func<T, bool>
predicate to a predicate which can be applied against the Entity Framework context.
The generic models & Entity Framework models have exactly the same property names & I already have a class to perform the property value mappings between the two. Is there a way to convert the target type of the generic model delegate to that of the Entity Framework model?
An example of what I'm attempting to do:
Given this delegate: func = Func<Schema.Data.Order, bool>
I want to convert it to: dbFunc = Func<Models.Order, bool>
And apply it to the context: ctx.Orders.Where(dbDel)
I found this post, but I can't piece together how to perform the conversion. Been bumping my head against this the whole evening, so any help would be greatly appreciated!
UPDATE
The original question & requirements seem to have been a bit vague, so I'll elaborate on my implementation & my requirements. The following code samples have been amended to use Expression<Func<TIn, TOut>>
& not Func<TIn, TOut>
, based on the suggestions from hvd & Alexei.
I have an interface & a set of classes that represent my data layer. These act as a façade over the data source, allowing for different implementations in order to access the database. I want to be able to pass through additional filter criteria as a predicate & apply this to the underlying data source. But since the façade is separate from the underlying implementation, the predicate is defined using the façade model classes. Furthermore, the façade model class properties have the same naming as that of my implementation, so direct property assignments using reflection, for example, is possible.
My façade implementation:
namespace Schema.Data
{
public interface IDataStore
{
public IEnumerable<Order> GetOrders(string custCode, Expression<Func<Order, bool>> exp);
}
public class Order
{
public string CustomerCode { get; set; }
public string OrderNumber { get; set; }
}
}
I then implement the interface in a separate namespace, using Entity Framework to query my database:
namespace Data.EF
{
// Entity Framework model is in this same namespace
public class DataStore : Schema.Data.IDataStore
{
public IEnumerable<Schema.Data.Order> GetOrders(string custCode, Expression<Func<Schema.Data.Order, bool>> exp)
{
using (var ctx = new MyDatabaseEntities()) {
// TODO: Convert "exp" to Expression<Func<Data.EF.Order, bool>> to pass it in below
var orders = ctx.Orders.Where(e => e.CustomerCode == custCode).Where(dbExp ?? (n => true));
// handling the retrieved data & returning result goes here
}
}
}
}