I am working on winRT and entity framework (to SQL), the layer that communicates between them is WCF Service. In the entity framework I am using the Repository Pattern and I have the method:
public IQueryable<User> GetBySearch(Expression<Func<User, bool>> search)
{
return this.Context.Users.Where(search);
}
Everything works fine, but when I add it to WCF
[OperationContract]
IQueryable<User> GetUserBySearch(Expression<Func<User, bool>> search);
and:
public IQueryable<User> GetUserBySearch(Expression<Func<User, bool>> search)
{
IUser user = new UserRepository();
return user.GetBySearch(search);
}
But the problem that Expression is not serializable, therefore, WCF can't serialize it. So I thought to inherit from it and make it [Serializable] but the problem that it is a sealed class.
Can someone help me to solve the problem?
WCF doesn't play well with Iqueryable and lambdas if your are using Entity Framework. This is a quick and dirty solution, adapt it to your needs.
Change the service contract to
[OperationContract]
IEnumerable<User> GetEventBySearch(UserCriteria search);
Where UserCriteria is a DataContract that contains a property for every search criteria that you need - example:
[DataContract]
public class UserCriteria
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
// add a property for each search criteria....
}
Service implementation:
public IEnumerable<User> GetEventBySearch(UserCriteria search)
{
IUser user = new UserRepository();
Expression<Func<User, bool>> criteria = BuildExpression(search);
return user.GetBySearch(criteria).AsEnumerable();
}
private Expression<Func<User, bool>> BuildExpression(UserCriteria search)
{
// build lambda expression here
}
Changeing Your Expression To Func , You Can Use BinaryFormatter Or Other Serializers To Serialize It As You Wish
You can use ServicePredicateBuilder
to serialize expressions.
http://www.codeproject.com/Articles/851187/ServicePredicateBuilder-for-creating-Serializable