Click here to Skip to main content
15,883,883 members
Articles / Web Development / ASP.NET
Tip/Trick

ServicePredicateBuilder for creating Serializable Expressions

,
Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
30 Nov 2015CPOL 36.8K   268   12   17
A library for creating .Net Serializable Expressions to send via WCF services

Download ServicePredicateBuilder.zip 15.8KB

Introduction

If you worked with WCF and EntityFramework, you faced with a big problem. Serializing Expressions

As you know, You can't serilize .Net Expression. so, you will have two choices:
1. Creating a method (Operation Contract) for each needing.
2. Creating another thing (class) to add predicates in a serializable form and send it via services.

ServicePredicateBuilde is that it. you can create predicates with it and send it via services and in service side get the expressions easily.

Background

There are some other libraries to do that, you can find them with googling 'serializable expression'
Unfortunately, most of them are old and don't update anymore. We couldn't use them easily.

Using the code

Install-Package ServicePredicateBuilder

Let us a review on ServicePredicateBuilder class

C#
[Serializable]
[DataContract]
public class ServicePredicateBuilder<TEntity> where TEntity : class
{
	/// <summary>
	/// Conditions
	/// </summary>
	[DataMember]
	public Criteria<TEntity> Criteria { get; set; }

	/// <summary>
	/// Sorting consitions
	/// </summary>
	[DataMember]
	public SortCondition<TEntity> SortCondition { get; set; }

	/// <summary>
	/// Navigation Properties to include in string format
	/// </summary>
	[DataMember]
	public List<string> IncludedNavigationProperties { get; set; }

	/// <summary>
	/// Navigation Properties to include in expression format
	/// There is not a difference between use `IncludedNavigationPropertiesExpression` Or `IncludedNavigationProperties`
	/// but if you have some navigation properties on `n` side of relation, you have to use `IncludedNavigationProperties`
	/// </summary>
	private List<Expression<Func<TEntity, object>>> _includedNavigationPropertiesExpression;
	public List<Expression<Func<TEntity, object>>> IncludedNavigationPropertiesExpression
	{
		...
	}

	/// <summary>
	/// Pagination data for getting getting data as paging
	/// </summary>
	[DataMember]
	public PaginationData PaginationData { get; set; }

	public ServicePredicateBuilder<TDestination> Cast<TDestination>() where TDestination : class
	{
		...
	}
}

Now, Let us code with ServicePredicateBuilder
At first, assume we have an Entity named User, Now we wanna create a predicate on User

C#
/////////////////////////////////////////
// In Client application
/////////////////////////////////////////
ServicePredicateBuilder servicePredicateBuilder = new ServicePredicateBuilder
{
	// navigation properties you wanna add  to entity
	IncludedNavigationProperties = new List<string> { "Attachments", "Posts" },
	
	// data of pagination result, you can leat it to null if you don&#39;t have pagination	
	PaginationData = new PaginationData 
	{
		PageNumber = page, // destination page number
		ItemsPerPage = itemsPerPage // items per each pages
	}
};

// Filtering 
Criteria<User> firstCritaria = Critaria.True<User>();
firstCritaria = firstCritaria.And(entity => entity.FirstName, OperatorEnum.Like, "Mohammad");
firstCritaria = firstCritaria.And>(entity =>entity.LastName, OperatorEnum.Like, "Dayyan");
firstCritaria = firstCritaria.And(entity =>entity.Comments.Count, OperatorEnum.GreaterThanOrEqual, 5);

Criteria<User> secondCritaria = Critaria.True<User>();
secondCritaria = secondCritaria.And(entity =>entity.FirstName, OperatorEnum.Like, "Vahid");
secondCritaria = secondCritaria.And(entity =>entity.LastName, OperatorEnum.Like, "Jafari");
secondCritaria = secondCritaria.And(entity =>entity.Comments.Count, OperatorEnum.GreaterThanOrEqual, 5);

Criteria<User> finalCritaria = firstCritaria.Or(secondCritaria);

servicePredicateBuilder.Critaria = finalCritaria;

// Sorting
SortCondition<User> sortCondition = SortCondition<User>.OrderBy(q=>q.FirstName);
sortCondition = sortCondition.ThenByDescending(q => q.LastName);
								
List<User> users = clientService.GetUser(servicePredicateBuilder);

/////////////////////////////////////////
// In Service side(WCF) method (Operation Contract)
/////////////////////////////////////////
[OperationContract]
public List<User> GetUser(ServicePredicateBuilder<User> servicePredicateBuilder)
{
	using(ModelEntities context = new ModelEntities())
	{
		// IEnumerable Sorting Func
		Func<IEnumerable<User>, IOrderedQueryable<User>> enumerableSortingFunc = servicePredicateBuilder.SortCondition.GetIEnumerableSortingFunc();
		
		// IQueryable sorting Func
		Func<IQueryable<User>, IOrderedQueryable<User>> queryableSortingFunc = servicePredicateBuilder.SortCondition.GetIQueryableSortingFunc();
		
		// expression for filtering
		Expression<Func<User, bool>> predicate = servicePredicateBuilder.Criteria.GetExpression();
		
		return enumerableSortingFunc(context.where(predicate));
	}
}

History

15th August 2015: First Post
6th October 2015: fix a bug in GetIEnumerableSortingExpression
29th November 2015: Support > >= < <= operators for string fields
30th November 2015: Fix a bug in GetExpression method

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
BugBug in Criteria.cs with ConvertConditionToExpresion Pin
Viperchen00712-Jun-16 1:58
Viperchen00712-Jun-16 1:58 
GeneralRe: Bug in Criteria.cs with ConvertConditionToExpresion Pin
Mohammad Dayyan12-Jun-16 2:36
Mohammad Dayyan12-Jun-16 2:36 
GeneralRe: Bug in Criteria.cs with ConvertConditionToExpresion Pin
Viperchen00712-Jun-16 4:17
Viperchen00712-Jun-16 4:17 
GeneralRe: Bug in Criteria.cs with ConvertConditionToExpresion Pin
Mohammad Dayyan12-Jun-16 19:56
Mohammad Dayyan12-Jun-16 19:56 
QuestionHave you consider to post this as a tip? Pin
Nelek30-Nov-15 2:49
protectorNelek30-Nov-15 2:49 
QuestionHow do you handle sorting and paging in WCF object? Pin
nfaruqi24-Oct-15 17:51
nfaruqi24-Oct-15 17:51 
AnswerRe: How do you handle sorting and paging in WCF object? Pin
Mohammad Dayyan25-Oct-15 19:01
Mohammad Dayyan25-Oct-15 19:01 
GeneralRe: How do you handle sorting and paging in WCF object? Pin
Member 76663826-Oct-15 16:23
Member 76663826-Oct-15 16:23 
QuestionSortCondition error Pin
Edgar Toledo22-Sep-15 4:20
Edgar Toledo22-Sep-15 4:20 
AnswerRe: SortCondition error Pin
Mohammad Dayyan22-Sep-15 18:14
Mohammad Dayyan22-Sep-15 18:14 
AnswerRe: SortCondition error Pin
Mohammad Dayyan6-Oct-15 3:21
Mohammad Dayyan6-Oct-15 3:21 
Questionvery nice Pin
Sacha Barber15-Aug-15 21:24
Sacha Barber15-Aug-15 21:24 
AnswerRe: very nice Pin
Mohammad Dayyan16-Aug-15 0:14
Mohammad Dayyan16-Aug-15 0:14 
GeneralRe: very nice Pin
Sacha Barber16-Aug-15 22:37
Sacha Barber16-Aug-15 22:37 
GeneralRe: very nice Pin
Mohammad Dayyan17-Aug-15 0:56
Mohammad Dayyan17-Aug-15 0:56 
QuestionInterlinq Pin
jogibear998815-Aug-15 3:51
jogibear998815-Aug-15 3:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.