2017年12月6日 星期三

How to get the all collection of sub-collection latest record

Environment
- .Net Framework 4.6.1
- EF 6.1.3
- Ms Visual Studio 2015

Table

Expected Result


Code
static public IEnumerable<History> GetAllLatestHistoryGroupedByUser(bool includedChild = false)
        {
            var predicate = PredicateBuilder.New<History>();

            if (includedChild)
            {
                predicate = predicate.And(c => c.IsDeleted == false);

                return dataContext.Historys.AsExpandable()
                                           .Where(predicate)
                                           .Include(c => c.User)
                                           .AsEnumerable()
                                           .GroupBy(c => c.userid)
                                           .Select(grp => grp.OrderByDescending(x => x.createdOn).FirstOrDefault());
            }
            else
            {
                return dataContext.Historys.AsExpandable()
                                           .Where(predicate)                                            
                                           .GroupBy(c => c.userid)
                                           .Select(grp => grp.OrderByDescending(x => x.createdOn).FirstOrDefault());
            }
        }            

*** Important Note ***
for include sub-collection, using .Include()

but very important that if any operation after .Include() such as .GroupBy(), .Select()
.Include() will negligible
So it need to add .AsEnumerable() before any operation

2017年12月5日 星期二

EF 6.1.3 Model First

Environment
- .Net Framework 4.6.1
- EF 6.1.3
- Ms Visual Studio 2015

Technique Applied
- Model First
- Fluent API
- Eager loading

        public MyContext() : base("DLSContext")
        {
            Configuration.LazyLoadingEnabled = false;
        }

- 1 to many configuration
            modelBuilder.Entity<User>()
                        .HasOptional(e => e.Creator)
                        .WithMany()
                        .HasForeignKey(m => m.CreatedBy);



- many to many configuration ( relationship table )
            // User2Right Table
            modelBuilder.Entity<User>()
                        .HasMany<UserRight>(r => r.UserRights)
                        .WithMany(u => u.PermittedUsers)
                        .Map(m =>
                                {
                                    m.MapLeftKey("UserId");
                                    m.MapRightKey("RightId");
                                    m.ToTable("User2Right");
                                }
                            );

.Map => generate relationship table in database


- virtual sub-collection
public virtual ICollection<UserRight> UserRights { get; set; }

- pluralizing

public DbSet<User> Users { get; set; }

modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();


- lower camelCase
   modelBuilder.Properties().Configure(c =>
            {
                var name = c.ClrPropertyInfo.Name;
                var newName = char.ToLower(name[0]) + name.Substring(1);
                c.HasColumnName(newName);
            });


- Key and Index Attribute

  
        [Index]  
        [Key]      
        public int Id { get; set; }



Model

User
public class User
    {
        public User()
        {
            if (this.UserRights == null)
            {
                this.UserRights = new HashSet<UserRight>();
            }
        }

        [Index]  
        [Key]      
        public int Id { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(255)]
        [Required]
        public string Name { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(125)]
        [Required]
        [Index("IX_Login", IsUnique = true)]
        public string Login { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(500)]
        [Required]
        public string Password { get; set; }

        [Column(TypeName = "bit")]        
        public bool IsDisabled { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(255)]
        [Required]
        public string Email { get; set; }

        [Required]
        public int FailedLoginAttempts { get; set; }

        public DateTime CreatedOn { get; set; }

        public int? CreatedBy { get; set; }

        public virtual User Creator { get; set; }

        public DateTime ModifiedOn { get; set; }

        public int? ModifiedBy { get; set; }

        public virtual User Modifier { get; set; }

        [Column(TypeName = "bit")]
        [Required]
        public bool IsDeleted { get; set; }

        public virtual ICollection<UserRight> UserRights { get; set; }
        public virtual ICollection<Status> StatusesCreated { get; set; }
        public virtual ICollection<Status> StatusesModified { get; set; }

    }

UserRight
public class UserRight
    {
        public UserRight()
        {
            if (this.PermittedUsers == null)
            {
                this.PermittedUsers = new HashSet<User>();
            }
        }

        [Index]
        [Key]
        [Required]
        public int Id { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(255)]
        [Required]
        public string Name { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(255)]
        public string Description { get; set; }

        public DateTime CreatedOn { get; set; }

        public int? CreatedBy { get; set; }

        public User Creator { get; set; }

        public DateTime ModifiedOn { get; set; }

        public int? ModifiedBy { get; set; }

        public virtual User Modifier { get; set; }

        [Column(TypeName = "bit")]
        [Required]
        public bool IsDeleted { get; set; }

        public virtual ICollection<User> PermittedUsers { get; set; }

    }

Status
 public class Status
    {
        [Index]
        [Key]
        public int Id { get; set; }

        [Column(TypeName = "nvarchar")]
        [StringLength(255)]
        [Required]
        public string Name { get; set; }

        public DateTime CreatedOn { get; set; }

        public int? CreatedBy { get; set; }
        public virtual User Creator { get; set; }

        public DateTime ModifiedOn { get; set; }

        public int? ModifiedBy { get; set; }

        public virtual User Modifier { get; set; }

        [Column(TypeName = "bit")]
        [Required]
        public bool IsDeleted { get; set; }

        public virtual ICollection<Contact> Contacts { get; set; }
    }


DAL

Context
public class MyContext : DbContext
    {
        public MyContext() : base("MyContext")
        {
            Configuration.LazyLoadingEnabled = false;
        }
        public DbSet<User> Users { get; set; }
        public DbSet<UserRight> UserRights { get; set; }        
        public DbSet<Status> Statuses { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Pluralizing
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            // lower camelCase
            modelBuilder.Properties().Configure(c =>
            {
                var name = c.ClrPropertyInfo.Name;
                var newName = char.ToLower(name[0]) + name.Substring(1);
                c.HasColumnName(newName);
            });

            // User Table 
            modelBuilder.Entity<User>()
                        .HasOptional(e => e.Creator)
                        .WithMany()
                        .HasForeignKey(m => m.CreatedBy);

            modelBuilder.Entity<User>()
                        .HasOptional(e => e.Modifier)
                        .WithMany()
                        .HasForeignKey(m => m.ModifiedBy);

            // User2Right Table
            modelBuilder.Entity<User>()
                        .HasMany<UserRight>(r => r.UserRights)
                        .WithMany(u => u.PermittedUsers)
                        .Map(m =>
                                {
                                    m.MapLeftKey("UserId");
                                    m.MapRightKey("RightId");
                                    m.ToTable("User2Right");
                                }
                            );              

            // Status Table
            modelBuilder.Entity<Status>()
                        .HasRequired(c => c.Creator)
                        .WithMany(u => u.StatusesCreated)
                        .HasForeignKey(c => c.CreatedBy)
                        .WillCascadeOnDelete(false);

            modelBuilder.Entity<Status>()
                        .HasRequired(c => c.Modifier)
                        .WithMany(u => u.StatusesModified)
                        .HasForeignKey(c => c.ModifiedBy)
                        .WillCascadeOnDelete(false);
            
        }
    }

Initializer
public class MyInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<MyContext>
    {
        protected override void Seed(MyContext context)
        {
            // Create Master User
            var systemUser = new User { Name = "System Admin", Login = "System Admin", Password = "1234567890", IsDisabled = false, Email = "abc", FailedLoginAttempts = 0, CreatedOn = DateTime.Today, ModifiedOn = DateTime.Today, IsDeleted = false };
            context.Users.Add(systemUser);
            context.SaveChanges();

            // Create User Right
            var userRights = new List<UserRight>
            {
                new UserRight { Name = "Administrative", Description = "Administrative Permission", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false },
                new UserRight { Name = "Super User", Description = "Super User Permission", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false },
                new UserRight { Name = "Dashboard Read", Description = "Read Permission for Dashboard", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false },
                new UserRight { Name = "Dashboard Write", Description = "Write Permission for Dashboard", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false },                
            };
            userRights.ForEach(u => context.UserRights.Add(u));
            context.SaveChanges();           

            // Create Status
            var statuses = new List<Status>
            {
                new Status { Name = "Active", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false },
                new Status { Name = "InActive", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false },
                new Status { Name = "Pending", CreatedOn=DateTime.Today, Creator=systemUser, ModifiedOn=DateTime.Today, Modifier=systemUser, IsDeleted=false }
            };
            statuses.ForEach(u => context.Statuses.Add(u));
            context.SaveChanges();           

            // Create User
            var users = new List<User>
            {
                new User { Name = "User A", Login = "userA", Password = "1234567890", IsDisabled = false, Email = "userA@mydomain.com", FailedLoginAttempts = 0, Creator=systemUser, CreatedOn = DateTime.Today, Modifier=systemUser, ModifiedOn = DateTime.Today, IsDeleted = false },
                new User { Name = "User B", Login = "userB", Password = "1234567890", IsDisabled = false, Email = "userB@mydomain.com", FailedLoginAttempts = 0, Creator=systemUser, CreatedOn = DateTime.Today, Modifier=systemUser, ModifiedOn = DateTime.Today, IsDeleted = false },
            };
            users.ForEach(u => u.UserRights.Add(context.UserRights.Where(ur => ur.Name == "Administrative").FirstOrDefault()));
            users.ForEach(u => context.Users.Add(u));
            context.SaveChanges();
            

        }
    }    


DAO

constant
    public enum SearchOperatorOption
    {
        And,
        Or
    };
    public enum SearchDateTimeOption
    {
        Inclusive,
        Exclusive
    };



UserService
static public class UserService
    {
        private static MyContext dataContext = new MyContext();

        static public IQueryable<User> SearchUser(SearchOperatorOption searchOperatorOption = SearchOperatorOption.And,
                                                  SearchDateTimeOption searchDateTimeOption = SearchDateTimeOption.Inclusive,
                                                  bool includedChild = false,
                                                  int? id = null,
                                                  string name = null,
                                                  string login = null,
                                                  bool? isDisabled = null,
                                                  string email = null,
                                                  int? failedLoginAttempts = null,
                                                  DateTime? createdFrom = null,
                                                  DateTime? createdTo = null,
                                                  int? createdBy = null,
                                                  DateTime? modifiedFrom = null,
                                                  DateTime? modifiedTo = null,
                                                  int? modifiedBy = null,
                                                  bool? isDeleted = null)
        {            
            var predicate = PredicateBuilder.New<User>();

            switch (searchOperatorOption)
            {
                #region SearchOperatorOption.And
                case SearchOperatorOption.And:
                    {
                        // Id
                        if (id != null)
                        {
                            predicate = predicate.And(u => u.Id == id);
                        }

                        // Name
                        if (!string.IsNullOrWhiteSpace(name))
                        {
                            predicate = predicate.And(u => u.Name.Contains(name));
                        }

                        // Login
                        if (!string.IsNullOrWhiteSpace(login))
                        {
                            predicate = predicate.And(u => u.Login.Contains(login));
                        }

                        // IsDisabled
                        if (isDisabled != null)
                        {
                            predicate = predicate.And(u => u.IsDisabled == isDisabled);
                        }

                        // Email
                        if (!string.IsNullOrWhiteSpace(email))
                        {
                            predicate = predicate.And(u => u.Email.Contains(email));
                        }

                        // FailedLoginAttempts
                        if (failedLoginAttempts != null)
                        {
                            predicate = predicate.And(u => u.FailedLoginAttempts >= failedLoginAttempts);
                        }

                        // CreatedOn
                        if (createdFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(u => u.CreatedOn >= createdFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(u => u.CreatedOn > createdFrom);
                                        break;
                                    }
                            }
                        }

                        // CreatedOn
                        if (createdTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(u => u.CreatedOn <= createdTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(u => u.CreatedOn < createdTo);
                                        break;
                                    }
                            }
                        }

                        // CreatedBy
                        if (createdBy != null)
                        {
                            predicate = predicate.And(u => u.CreatedBy == createdBy);
                        }

                        // ModifiedOn
                        if (modifiedFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(u => u.ModifiedOn >= modifiedFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(u => u.ModifiedOn > modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedOn
                        if (modifiedTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(u => u.ModifiedOn <= modifiedTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(u => u.ModifiedOn < modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedBy
                        if (modifiedBy != null)
                        {
                            predicate = predicate.And(u => u.ModifiedBy == modifiedBy);
                        }

                        // IsDeleted
                        if (isDeleted != null)
                        {
                            predicate = predicate.And(u => u.IsDeleted == isDeleted);
                        }
                        
                        break;
                    }
                #endregion
                #region SearchOperatorOption.Or
                case SearchOperatorOption.Or:
                    {
                        // Id
                        if (id != null)
                        {
                            predicate = predicate.Or(u => u.Id == id);
                        }

                        // Name
                        if (!string.IsNullOrWhiteSpace(name))
                        {
                            predicate = predicate.Or(u => u.Name.Contains(name));
                        }

                        // Login
                        if (!string.IsNullOrWhiteSpace(login))
                        {
                            predicate = predicate.Or(u => u.Login.Contains(login));
                        }

                        // IsDisabled
                        if (isDisabled != null)
                        {
                            predicate = predicate.Or(u => u.IsDisabled == isDisabled);
                        }

                        // Email
                        if (!string.IsNullOrWhiteSpace(email))
                        {
                            predicate = predicate.Or(u => u.Email.Contains(email));
                        }

                        // FailedLoginAttempts
                        if (failedLoginAttempts != null)
                        {
                            predicate = predicate.Or(u => u.FailedLoginAttempts >= failedLoginAttempts);
                        }

                        // CreatedOn
                        if (createdFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(u => u.CreatedOn >= createdFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(u => u.CreatedOn > createdFrom);
                                        break;
                                    }
                            }
                        }

                        // CreatedOn
                        if (createdTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(u => u.CreatedOn <= createdTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(u => u.CreatedOn < createdTo);
                                        break;
                                    }
                            }
                        }

                        // CreatedBy
                        if (createdBy != null)
                        {
                            predicate = predicate.Or(u => u.CreatedBy == createdBy);
                        }

                        // ModifiedOn
                        if (modifiedFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(u => u.ModifiedOn >= modifiedFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(u => u.ModifiedOn > modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedOn
                        if (modifiedTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(u => u.ModifiedOn <= modifiedTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(u => u.ModifiedOn < modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedBy
                        if (modifiedBy != null)
                        {
                            predicate = predicate.Or(u => u.ModifiedBy == modifiedBy);
                        }

                        // IsDeleted
                        if (isDeleted != null)
                        {
                            predicate = predicate.Or(u => u.IsDeleted == isDeleted);
                        }

                        break;
                    }
                    #endregion
            }

            if (includedChild)
            {
                return dataContext.Users.AsExpandable().Where(predicate).Include(u => u.Creator).Include(u => u.Modifier);
            }
            else
            {
                return dataContext.Users.AsExpandable().Where(predicate);
            }
        }

        #region Basic Method
        static public IEnumerable<User> GetAllUser(bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, isDeleted: false).ToList();
        }        

        static public User GetUserById(int id, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, id: id).FirstOrDefault();
        }

        static public IEnumerable<User> GetUserByName(string name, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, name: name);
        }

        static public IEnumerable<User> GetUsersByName(bool includedChild = false, params string[] name)
        {
            throw new NotImplementedException();            
        }
        static public User GetUserByLogin(string login, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, login: login).FirstOrDefault();
        }

        static public IEnumerable<User> GetAllDisabledUser(bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, isDisabled: true).ToList();
        }

        static public IEnumerable<User> GetUserByEmail(string email, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, email: email);
        }

        static public IEnumerable<User> GetUserByCreationDate(DateTime? from, DateTime? to, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, createdFrom: from, createdTo: to);
        }

        static public IEnumerable<User> GetUserByCreator(int creatorId, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, createdBy: creatorId);
        }

        static public IEnumerable<User> GetUserByCreator(User creator, bool includedChild = false)
        {
            return GetUserByCreator(includedChild: includedChild, creatorId: creator.Id);
        }

        static public IEnumerable<User> GetUserByModificationDate(DateTime? from, DateTime? to, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, modifiedFrom: from, modifiedTo: to);
        }

        static public IEnumerable<User> GetUserByModifier(int modifierId, bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, modifiedBy: modifierId);
        }

        static public IEnumerable<User> GetUserByModifier(User modifier, bool includedChild = false)
        {
            return GetUserByModifier(includedChild: includedChild, modifierId: modifier.Id);
        }

        static public IEnumerable<User> GetAllDeletedUser(bool includedChild = false)
        {
            return SearchUser(includedChild: includedChild, isDeleted: true).ToList();
        }
        #endregion

        #region Extend Method
        #endregion
    }


How to use PredicateBuilder to build dynamic query

Environment
- .Net Framework 4.6.1
- EF 6.1.3
- Ms Visual Studio 2015

using LinqKit;
using System.Data.Entity;
using System.Linq;

Usage
Multiple search criteria (like search filter)



static public IQueryable<Contact> SearchContact(SearchOperatorOption searchOperatorOption = SearchOperatorOption.And,
            SearchDateTimeOption searchDateTimeOption = SearchDateTimeOption.Inclusive,
            bool includedChild = false,
            int? id = null,
            string name = null,
            string telephone = null,
            string fax = null,
            string contactPerson = null,
            string email = null,
            int? categoryId = null,
            int? statusId = null,
            DateTime? createdFrom = null,
            DateTime? createdTo = null,
            int? createdBy = null,
            DateTime? modifiedFrom = null,
            DateTime? modifiedTo = null,
            int? modifiedBy = null,
            bool? isDeleted = null)
        {            
            var predicate = PredicateBuilder.New<Contact>();

            switch (searchOperatorOption)
            {
                #region SearchOperatorOption.And
                case SearchOperatorOption.And:
                    {
                        // Id
                        if (id != null)
                        {
                            predicate = predicate.And(c => c.Id == id);
                        }

                        // Name
                        if (!string.IsNullOrWhiteSpace(name))
                        {
                            predicate = predicate.And(c => c.Name.Contains(name));
                        }                       

                        // Telephone
                        if (!string.IsNullOrWhiteSpace(telephone))
                        {
                            predicate = predicate.And(c => c.Telephone.Contains(telephone));
                        }

                        // Fax
                        if (!string.IsNullOrWhiteSpace(fax))
                        {
                            predicate = predicate.And(c => c.Fax.Contains(fax));
                        }

                        // ContactPerson
                        if (!string.IsNullOrWhiteSpace(contactPerson))
                        {
                            predicate = predicate.And(c => c.ContactPerson.Contains(contactPerson));
                        }

                        // Email
                        if (!string.IsNullOrWhiteSpace(email))
                        {
                            predicate = predicate.And(c => c.Email.Contains(email));
                        }

                        // CategoryId
                        if (categoryId != null)
                        {
                            predicate = predicate.And(c => c.CategoryId == categoryId);
                        }

                        // StatusId
                        if (statusId != null)
                        {
                            predicate = predicate.And(c => c.StatusId == statusId);
                        }

                        // CreatedOn
                        if (createdFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(c => c.CreatedOn >= createdFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(c => c.CreatedOn > createdFrom);
                                        break;
                                    }
                            }
                        }

                        // CreatedOn
                        if (createdTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(c => c.CreatedOn <= createdTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(c => c.CreatedOn < createdTo);
                                        break;
                                    }
                            }
                        }

                        // CreatedBy
                        if (createdBy != null)
                        {
                            predicate = predicate.And(c => c.CreatedBy == createdBy);
                        }

                        // ModifiedOn
                        if (modifiedFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(c => c.ModifiedOn >= modifiedFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(c => c.ModifiedOn > modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedOn
                        if (modifiedTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.And(c => c.ModifiedOn <= modifiedTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.And(c => c.ModifiedOn < modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedBy
                        if (modifiedBy != null)
                        {
                            predicate = predicate.And(c => c.ModifiedBy == modifiedBy);
                        }

                        // IsDeleted
                        if (isDeleted != null)
                        {
                            predicate = predicate.And(c => c.IsDeleted == isDeleted);
                        }
                        
                        break;
                    }
                #endregion
                #region SearchOperatorOption.Or
                case SearchOperatorOption.Or:
                    {
                        // Id
                        if (id != null)
                        {
                            predicate = predicate.Or(c => c.Id == id);
                        }

                        // Name
                        if (!string.IsNullOrWhiteSpace(name))
                        {
                            predicate = predicate.Or(c => c.Name.Contains(name));
                        }                     

                        // Telephone
                        if (!string.IsNullOrWhiteSpace(telephone))
                        {
                            predicate = predicate.Or(c => c.Telephone.Contains(telephone));
                        }

                        // Fax
                        if (!string.IsNullOrWhiteSpace(fax))
                        {
                            predicate = predicate.Or(c => c.Fax.Contains(fax));
                        }

                        // ContactPerson
                        if (!string.IsNullOrWhiteSpace(contactPerson))
                        {
                            predicate = predicate.Or(c => c.ContactPerson.Contains(contactPerson));
                        }

                        // Email
                        if (!string.IsNullOrWhiteSpace(email))
                        {
                            predicate = predicate.Or(c => c.Email.Contains(email));
                        }

                        // CategoryId
                        if (categoryId != null)
                        {
                            predicate = predicate.Or(c => c.CategoryId == categoryId);
                        }

                        // StatusId
                        if (statusId != null)
                        {
                            predicate = predicate.Or(c => c.StatusId == statusId);
                        }

                        // CreatedOn
                        if (createdFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(c => c.CreatedOn >= createdFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(c => c.CreatedOn > createdFrom);
                                        break;
                                    }
                            }
                        }

                        // CreatedOn
                        if (createdTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(c => c.CreatedOn <= createdTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(c => c.CreatedOn < createdTo);
                                        break;
                                    }
                            }
                        }

                        // CreatedBy
                        if (createdBy != null)
                        {
                            predicate = predicate.Or(c => c.CreatedBy == createdBy);
                        }

                        // ModifiedOn
                        if (modifiedFrom != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(c => c.ModifiedOn >= modifiedFrom);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(c => c.ModifiedOn > modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedOn
                        if (modifiedTo != null)
                        {
                            switch (searchDateTimeOption)
                            {
                                case SearchDateTimeOption.Inclusive:
                                    {
                                        predicate = predicate.Or(c => c.ModifiedOn <= modifiedTo);
                                        break;
                                    }
                                case SearchDateTimeOption.Exclusive:
                                    {
                                        predicate = predicate.Or(c => c.ModifiedOn < modifiedFrom);
                                        break;
                                    }
                            }
                        }

                        // ModifiedBy
                        if (modifiedBy != null)
                        {
                            predicate = predicate.Or(c => c.ModifiedBy == modifiedBy);
                        }

                        // IsDeleted
                        if (isDeleted != null)
                        {
                            predicate = predicate.Or(c => c.IsDeleted == isDeleted);
                        }

                        break;
                    }
                    #endregion
            }

            if (includedChild)
            {
                return dataContext.Contacts.AsExpandable().Where(predicate).Include(c => c.Creator)
                                                                           .Include(c => c.Modifier)
                                                                           .Include(c => c.Status)
                                                                           .Include(c => c.Category);
            }
            else
            {
                return dataContext.Contacts.AsExpandable().Where(predicate);
            }
        }




Reference : http://www.albahari.com/nutshell/predicatebuilder.aspx