Click here to Skip to main content
14,875,660 members
Articles / Web Development / ASP.NET
Tip/Trick
Posted 14 Aug 2015

Stats

28.1K views
259 downloads
12 bookmarked

ServicePredicateBuilder for creating Serializable Expressions

,
Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
30 Nov 2015CPOL
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)

Share

About the Authors

Mohammad Dayyan
Iran (Islamic Republic of) Iran (Islamic Republic of)
No Biography provided

VahidJafari
United States United States
No Biography provided

Comments and Discussions

 
BugBug in Criteria.cs with ConvertConditionToExpresion Pin
Viperchen00712-Jun-16 1:58
MemberViperchen00712-Jun-16 1:58 
GeneralRe: Bug in Criteria.cs with ConvertConditionToExpresion Pin
Mohammad Dayyan12-Jun-16 2:36
MemberMohammad Dayyan12-Jun-16 2:36 
GeneralRe: Bug in Criteria.cs with ConvertConditionToExpresion Pin
Viperchen00712-Jun-16 4:17
MemberViperchen00712-Jun-16 4:17 
GeneralRe: Bug in Criteria.cs with ConvertConditionToExpresion Pin
Mohammad Dayyan12-Jun-16 19:56
MemberMohammad 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
Membernfaruqi24-Oct-15 17:51 
AnswerRe: How do you handle sorting and paging in WCF object? Pin
Mohammad Dayyan25-Oct-15 19:01
MemberMohammad Dayyan25-Oct-15 19:01 
GeneralRe: How do you handle sorting and paging in WCF object? Pin
Member 76663826-Oct-15 16:23
MemberMember 76663826-Oct-15 16:23 
QuestionSortCondition error Pin
Edgar Toledo22-Sep-15 4:20
MemberEdgar Toledo22-Sep-15 4:20 
AnswerRe: SortCondition error Pin
Mohammad Dayyan22-Sep-15 18:14
MemberMohammad Dayyan22-Sep-15 18:14 
AnswerRe: SortCondition error Pin
Mohammad Dayyan6-Oct-15 3:21
MemberMohammad Dayyan6-Oct-15 3:21 
Questionvery nice Pin
Sacha Barber15-Aug-15 21:24
mvaSacha Barber15-Aug-15 21:24 
AnswerRe: very nice Pin
Mohammad Dayyan16-Aug-15 0:14
MemberMohammad Dayyan16-Aug-15 0:14 
GeneralRe: very nice Pin
Sacha Barber16-Aug-15 22:37
mvaSacha Barber16-Aug-15 22:37 
GeneralRe: very nice Pin
Mohammad Dayyan17-Aug-15 0:56
MemberMohammad Dayyan17-Aug-15 0:56 
QuestionInterlinq Pin
jogibear998815-Aug-15 3:51
Memberjogibear998815-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.