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

2017年11月22日 星期三

How to push value into structured array in Angularjs v1.x

How to push value into structured array in Angularjs v1.x 

Background
- angularjs v1.x
          
  // define $scope variables for store result
  $scope.roles = [];

        var getSomething = function () {            
            return $http({
                method: 'GET',
                url: 'http://www.somewhere.com/GetSomething'
            }).then(function successCallback(response) {
    // Assume return value is something like "ValueA, ValueB, ValueC, ValueD"
                angular.forEach(response.data, function(value, key){
     
     //target structure like this
     //  roles [ 
     //   {
     //   value : "ValueA",
     //   attr1 : false,
     //   attr2 : "attr2 value"
     //   },
     //   {
     //   value : "ValueB",
     //   attr1 : false,
     //   attr2 : "attr2 value"
     //   },
     //   {
     //   value : "ValueC",
     //   attr1 : false,
     //   attr2 : "attr2 value"
     //   },
     //   {
     //   value : "ValueD",
     //   attr1 : false,
     //   attr2 : "attr2 value"
     //   }     
     //       ]    
                    $scope.roles.push( {value:value, attr1:false, attr2:"attr2 value"} )
                });                
            }, function errorCallback(response) {                
            });
        };

2017年11月16日 星期四

How to call Modal Dialog (Custom html view) on Umbraco AngularJs

How to call Modal Dialog (Custom html view) on Umbraco AngularJs 


Background
- angularjs v1.x


view.html

<div ng-controller="myController">
    <div>
    <a class="btn" ng-disabled="actionInProgress" ng-click="toggleModal(functionA())" prevent-default>
        functionA
    </a>
    <a class="btn" ng-disabled="actionInProgress" ng-click="toggleModal(functionB())" prevent-default>
        functionB
    </a>
    <a class="btn" ng-disabled="actionInProgress" ng-click="toggleModal(functionC())" prevent-default>
        functionC
    </a>

    <modal-dialog callback-fn='actionName' show='modalShown' width='200px' height='15%'><p>Are you sure to proceed action?</p>
</div>


directive

'use strict';
var umbracoApp = angular.module('umbraco.directives');

umbracoApp.directive('modalDialog', function () {
    return {
        restrict: 'E',
        scope: {
            show: '=',
            actionName: '&callbackFn'            
        },
        replace: true, // Replace with the template below
        transclude: true, // we want to insert custom content inside the directive
        link: function (scope, element, attrs) {            
            scope.dialogStyle = {};
            if (attrs.width) {
                scope.dialogStyle.width = attrs.width;
            };
            if (attrs.height) {
                scope.dialogStyle.height = attrs.height;
            };
            scope.hideModal = function () {
                scope.show = false;
            };
            scope.confirmedClick = function () {
                scope.$eval(scope.actionName());                
                scope.show = false;
            };
        },
        templateUrl: "/App_Plugins/ThreewoodActiveDirectory/template/modal.dialog.html"        
    };
});

controller

'use strict';

(function () {
    // Create controller variable
    function myController($scope, $http, $injector, userService, notificationsService) {        

     $scope.modalShown = false;
        $scope.actionName = "";
        $scope.toggleModal = function (action) {
            $scope.actionName = action;
            $scope.modalShown = !$scope.modalShown;
        };

        $scope.functionA = function () {
            var fn = function () {
                alert("functionA");
            }
            return fn;
        };

        $scope.functionB = function () {
            var fn = function () {
                alert("functionB");
            }
            return fn;
        };

        $scope.functionC = function () {
            var fn = function () {
                alert("functionC");
            }
            return fn;
        };
               
    };


    // Register the controller    
    angular.module("umbraco").controller("myController", myController);
})();


modal dialog view

<div class='ng-modal' ng-show='show'>
    <div class='ng-modal-overlay' ng-click='hideModal()'></div>
    <div class='ng-modal-dialog' ng-style='dialogStyle'>                
        <div class='ng-modal-dialog-content' ng-transclude></div>                
        <div class="ng-modal-dialog-button">
            <button id="no" class="btn btn-warning" ng-click='hideModal()'>No</button>
            <button id="yes" class="btn" confirmed-action="actionName()" ng-click="confirmedClick()">Yes</button>
        </div>        
    </div>
</div>


modal dialog css

.ng-modal-overlay {
  /* A dark translucent div that covers the whole screen */
  position:absolute;
  z-index:9999;
  top:0;
  left:0;
  width:100%;
  height:100%;
  background-color:#000000;
  opacity: 0.8;
}
.ng-modal-dialog {
  /* A centered div above the overlay with a box shadow. */
  z-index:10000;
  position: absolute;
  width: 50%; /* Default */

  /* Center the dialog */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);

  background-color: #fff;
  box-shadow: 4px 4px 80px #000;
  text-align: center;
  border-radius: 10px;
}
.ng-modal-dialog-content {
  padding:10px;
  text-align: center;
  font-weight: bold;
}
.ng-modal-close {
  position: absolute;
  top: 3px;
  right: 5px;
  padding: 5px;
  cursor: pointer;
  font-size: 120%;
  display: inline-block;
  font-weight: bold;
  font-family: 'arial', 'sans-serif';
}

.ng-modal-dialog-button {

}


AngularJs Pass function to directive without execute it.

HAngularJs Pass function to directive without execute it

Background
- angularjs v1.x


view

<div ng-controller="myController">
 <a class="btn" ng-click="someMethod(myFunction())" prevent-default></a>
</div>


controller

'use strict';

(function () {
    // Create controller variable
    function myController($scope) {        

       $scope.someMethod = function (action) {
          $scope.actionName = action;            
       };

       $scope.myFunction = function () {
       var fn = function () {
            alert("Hello There!");
          };
       return fn;
       }; 
    };

    // Register the controller    
    angular.module("umbraco").controller("myController", myController);
})();

Explantion

put the you own logic inside

var fn = function () {
    alert("Hello There!");
};

replace the alert by your own logic.

at last return the fn

and when pass the function

ng-click="someMethod(myFunction())"

myFunction must be include bracket (),

declare the function and assign a variable fn for that, it will not execute while parsing when the website startup. It just expression, it will execute it when you evaluate the expression in where you want to.

$eval($scope.actionName()); 

P.S The declaration of function very very critical, and end of the function must return fn

How to call Modal Dialog (Window) on Umbraco AngularJs

How to call Modal Dialog (Window) on Umbraco AngularJs 


Background
- angularjs v1.x


view.html

<div ng-controller="myController">
    <div>
        <button ng-confirm-click="Custom Message" class="btn" confirmed-click='confirmclick()' cancel-click='cancelClick()' >Test</button>        
    </div>
</div>


directive

'use strict';
var umbracoApp = angular.module('umbraco.directives');

umbracoApp.directive('ngConfirmClick', function () {
    return {        
        link: function (scope, element, attrs) {
            var msg = attrs.ngConfirmClick || "Are you sure?";
            var confirmClickAction = attrs.confirmedClick;
            var cancelClickAction = attrs.cancelClick;
            element.bind('click', function (event) {
                if (window.confirm(msg)) {
                    scope.$eval(confirmClickAction)                    
                }
                else
                {
                    scope.$eval(cancelClickAction)
                }
            });
        }        
    };
});

controller

'use strict';

(function () {
    // Create controller variable
    function MyController($scope) {        

        $scope.confirmclick = function (element) {
            alert("confirm clicked");
        };

        $scope.cancelClick = function (element) {            
            alert("cancel clicked");
        };        

    // Register the controller    
    angular.module("umbraco").controller("myController", MyController);
})();

2017年11月13日 星期一

2017年11月9日 星期四

Umbraco Language for Packages

Environment
- Umbraco version 7.7.4
- Applies to version 7.3.0 and newer


en-GB.xml sample file
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en-GB" intName="English (US)" localName="English (US)" lcid="" culture="en-US">
  <creator>
    <name>{Your Name}</name>
    <link>{Your Website}</link>
  </creator>
  <area alias="{Your Alias Name}">
    <!-- DASHBOARD -->
    <key alias="Dashboard.Title"><![CDATA[Welcome to Dashboard]]></key>
    <key alias="Dashboard.SubTitle"><![CDATA[Dashboard Subtitle.]]></key>
    <key alias="Dashboard.Description">
      <![CDATA[ Dashboard Description ]]>
    </key>
    <key alias="Dashboard.LatestChanges"><![CDATA[]]></key>
    <key alias="Dashboard.VersionHistory"><![CDATA[]]></key>
    <key alias="Dashboard.LoadButton">Load</key>
  </area>
</language>

<area alias="{Your Alias Name}">

For example:
<area alias="MyAlias">


dashboard.html sample
<div class="welcome-dashboard" ng-controller="My.Dashboard.ViewController">
    <div class="row-fluid">
        <div class="umb-sub-header">
   <h3 class="title"><localize key="MyAlias_Dashboard.Title"></localize></h3> 
   <div class="subtitle"><localize key="MyAlias_Dashboard.SubTitle"></localize></div>
   <div class="description"><localize key="MyAlias_Dashboard.Description"></localize></div>
        </div>
    </div>    

    <div class="row-fluid">
        <div class="btn-group">
            <a class="btn" href="#">                
                <localize key="MyAlias_Dashboard.LoadButton"></localize>         
            </a>           
        </div>
    </div>
</div>



Place the file under /app_plugins/mypackage/lang/en-GB.xml

naming convention of the key

{Area alias}_{Key alias}

Example : title

Area alias =  MyAlias
Key alias = Dashboard.Title

=> MyAlias_Dashboard.Title

P.S Please check and touch web.config file to reload the umbraco caches(NOT browser caches) in case the text displayed which is not expected (refreshed).


Reference:
Umbraco Official KB

2017年11月8日 星期三

LDAP simple query and C# approach

Find All user

(&(objectClass=user)(objectClass=person))

Find All active user 

(&(objectClass=user)(objectClass=person)(!userAccountControl:1.2.840.113556.1.4.803:=2))

Find All active user without empty email and display Name

(&(objectClass=user)(objectClass=person)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*)(displayName=*))


C# approach


public List<UserProfile> GetAllUser(string ldapQueryString)
        {
            try
            {
                using (HostingEnvironment.Impersonate())
                {
                    _directoryEntry = null;
                    DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot);
                    directorySearch.Filter = string.Format("(&(objectClass=user)(objectClass=person){0})", ldapQueryString);
                    directorySearch.PageSize = 500;
                    SearchResultCollection allUsers = directorySearch.FindAll();

                    if (allUsers != null)
                    {
                        List<UserProfile> users = new List<UserProfile>();
                        foreach (SearchResult u in allUsers)
                        {
                            DirectoryEntry de = new DirectoryEntry(u.Path);
                            users.Add(UserProfile.GetUser(de));
                        }
                        return users;
                    }
                    return null;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error<ActiveDirectoryHelper>("GetUserByFullName Exception: ", ex);
                return null;
            }
        }

UserProfile Class
public class UserProfile
    {
        private Guid _guid;
        private String _distinguishedName;
        private String _displayName;
        private String _firstName;
        private String _middleName;
        private String _lastName;
        private String _loginName;
        private String _loginNameWithDomain;
        private String _streetAddress;
        private String _city;
        private String _state;
        private String _postalCode;
        private String _country;
        private String _homePhone;
        private String _extension;
        private String _mobile;
        private String _fax;
        private String _emailAddress;
        private String _title;
        private String _company;
        private String _manager;
        private String _managerName;
        private String _department;

        public Guid GUID
        {
            get { return _guid; }
        }

        public string DistinguishedName
        {
            get { return _distinguishedName; }
        }             

        public String Department
        {
            get { return _department; }
        }

        public String FirstName
        {
            get { return _firstName; }
        }

        public String MiddleName
        {
            get { return _middleName; }
        }

        public String LastName
        {
            get { return _lastName; }
        }

        public String DisplayName
        {
            get { return _displayName; }
        }

        public String LoginName
        {
            get { return _loginName; }
        }

        public String LoginNameWithDomain
        {
            get { return _loginNameWithDomain; }
        }

        public String StreetAddress
        {
            get { return _streetAddress; }
        }

        public String City
        {
            get { return _city; }
        }

        public String State
        {
            get { return _state; }
        }

        public String PostalCode
        {
            get { return _postalCode; }
        }

        public String Country
        {
            get { return _country; }
        }

        public String HomePhone
        {
            get { return _homePhone; }
        }

        public String Extension
        {
            get { return _extension; }
        }

        public String Mobile
        {
            get { return _mobile; }
        }

        public String Fax
        {
            get { return _fax; }
        }

        public String EmailAddress
        {
            get { return _emailAddress; }
        }

        public String Title
        {
            get { return _title; }
        }

        public String Company
        {
            get { return _company; }
        }

        public UserProfile Manager
        {
            get
            {
                if (!String.IsNullOrEmpty(_managerName))
                {
                    ActiveDirectoryHelper activeDirectoryHelper = new ActiveDirectoryHelper();
                    return activeDirectoryHelper.GetUserByFullName(_managerName);
                }
                return null;
            }
        }

        public String ManagerName
        {
            get { return _managerName; }
        }


        private UserProfile(DirectoryEntry directoryUser)
        {

            String domainAddress;
            String domainName;

            _guid = directoryUser.Guid;
            _distinguishedName = GetProperty(directoryUser, Properties.DISTINGUISHEDNAME);
            _firstName = GetProperty(directoryUser, Properties.FIRSTNAME);
            _middleName = GetProperty(directoryUser, Properties.MIDDLENAME);
            _lastName = GetProperty(directoryUser, Properties.LASTNAME);
            _displayName = GetProperty(directoryUser, Properties.DISPLAYNAME);
            _loginName = GetProperty(directoryUser, Properties.LOGINNAME);
            String userPrincipalName = GetProperty(directoryUser, Properties.USERPRINCIPALNAME);

            if (!string.IsNullOrEmpty(userPrincipalName))
            {
                domainAddress = userPrincipalName.Split('@')[1];
            }
            else
            {
                domainAddress = String.Empty;
            }

            if (!string.IsNullOrEmpty(domainAddress))
            {
                domainName = domainAddress.Split('.').First();
            }
            else
            {
                domainName = String.Empty;
            }

            _loginNameWithDomain = String.Format(@"{0}\{1}", domainName, _loginName);
            _streetAddress = GetProperty(directoryUser, Properties.STREETADDRESS);
            _city = GetProperty(directoryUser, Properties.CITY);
            _state = GetProperty(directoryUser, Properties.STATE);
            _postalCode = GetProperty(directoryUser, Properties.POSTALCODE);
            _country = GetProperty(directoryUser, Properties.COUNTRY);
            _company = GetProperty(directoryUser, Properties.COMPANY);
            _department = GetProperty(directoryUser, Properties.DEPARTMENT);
            _homePhone = GetProperty(directoryUser, Properties.HOMEPHONE);
            _extension = GetProperty(directoryUser, Properties.EXTENSION);
            _mobile = GetProperty(directoryUser, Properties.MOBILE);
            _fax = GetProperty(directoryUser, Properties.FAX);
            _emailAddress = GetProperty(directoryUser, Properties.EMAILADDRESS);
            _title = GetProperty(directoryUser, Properties.TITLE);
            _manager = GetProperty(directoryUser, Properties.MANAGER);

            if (!String.IsNullOrEmpty(_manager))
            {
                String[] managerArray = _manager.Split(',');
                _managerName = managerArray[0].Replace("CN=", "");
            }
        }


        private static String GetProperty(DirectoryEntry userDetail, String propertyName)
        {
            if (userDetail.Properties.Contains(propertyName))
            {
                return userDetail.Properties[propertyName][0].ToString();
            }
            else
            {
                return string.Empty;
            }
        }

        public static UserProfile GetUser(DirectoryEntry directoryUser)
        {
            return new UserProfile(directoryUser);
        }
    }


Reference
LDAP Query Basics
KB for query disabled user

2017年11月7日 星期二

How to save the Umbraco member password via code

Environment
- Umbraco version 7.7.4


public static int CreateMember(string usernameWithDomain, string name, string email, string password = null, List<string> roleNames = null, List<KeyValuePair<string, string>> properties = null, string memberType = "Member")
        {            
            try
            {
                IMember member = ApplicationContext.Current.Services.MemberService.CreateMember(usernameWithDomain, email, name, memberType);

                member.IsApproved = true;
                if (properties != null)
                {
                    foreach (var property in properties)
                    {
                        member.SetValue(property.Key, property.Value);
                    }
                }

                ApplicationContext.Current.Services.MemberService.Save(member);

                if (string.IsNullOrEmpty(password))
                {
                    password = Guid.NewGuid().ToString().Substring(0, 8);
                }
                ApplicationContext.Current.Services.MemberService.SavePassword(member, password);
                
                if (roleNames != null)
                {
                    foreach (string roleName in roleNames)
                    {
                        if (!String.IsNullOrEmpty(roleName))
                        {
                            ApplicationContext.Current.Services.MemberService.AssignRole(member.Id, roleName);
                        }
                    }
                }

                LogHelper.Info<MemberHelper>(string.Format("{0}(name) created, {1}(id)", name, member.Id));
                return member.Id;
            }
            catch (Exception ex)
            {
                LogHelper.Error<MemberHelper>("CreateMember exception: ", ex);
                return -1;
            }
        }

web.config

allowManuallyChangingPassword="true" 

2017年10月29日 星期日

How to find LDAP server in Windows via command prompt

How to find LDAP server in Windows $> nslookup > set types=all > _ldap._tcp

How to remove locked USB External drive

To safely remove the drive: Open Command Prompt (cmd.exe). Type diskpart. Type list disk. Find your disk #, and type select disk [number here]. Type offline disk. You should be able to remove it now. Next time you plug it in, it won't be automatically mounted. So either use the command prompt again to make it online, or: Run diskmgmt.msc. Find the disk, right click, and choose "Online".

2017年10月26日 星期四

How to identify blocking in SQL Server

How to identify blocking in SQL Server



  • Activity Monitor
  • SQLServer:Locks Performance Object
  • DMVs
    • sys.dm_exec_requests
    • sys.dm_tran_locks
    • sys.dm_os_waiting_tasks
  • SQL Server Profiler Locks Event Category

exec sp_who2

select * from sys.dm_tran_locks

SELECT
OBJECT_NAME(p.OBJECT_ID) AS TableName,
resource_type, resource_description
FROM
sys.dm_tran_locks l
JOIN sys.partitions p ON l.resource_associated_entity_id = p.hobt_id

DBCC inputbuffer (SPID)

USE master;
GO
KILL spid | UOW [WITH STATUSONLY]
GO

DBCC opentran (Database)



2017年10月23日 星期一

How to find duplicate row in SQL

How to find duplicate row in SQL

Single Row

SELECT
    [RefID], COUNT(*)
FROM
    [myTable]
GROUP BY
    [RefID]
HAVING 
    COUNT(*) > 1

Multiple Row

SELECT
    name, email, COUNT(*)
FROM
    users
GROUP BY
    name, email
HAVING 
    COUNT(*) > 1

2017年10月19日 星期四

Umbraco Content Service Event Order

Environment
- Umbraco version 7.7.2


For Writer

Save and send to Approval

ContentService.SendingToPublish -> ContentService.Saved -> ContentService.SentToPublish

For Editor

Save and Publish

ContentService.Publishing -> ContentService.Saved -> ContentService.Published

2017年10月12日 星期四

How to self-referencing in Entity Framework via Code First

How to self-referencing in Entity Framework via Code First

Environment
- VS 2015 
- MVC 5
- .Net Framework 4.6.1
- Code First
- MS SQL 2012 Server



Model Class
User.cs
public class User
{
 [Index]  
 [Key]      
 public int Id { get; set; }

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

 [Column(TypeName = "nvarchar")]
 [StringLength(125)]
 [Required]
 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; }

 public int FailedLoginAttempts { 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")]
 public bool IsDeleted { get; set; }
}

Context Class
MyContext.cs
public class MyContext : DbContext
{
  #region Properties

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

  #endregion

  #region Ctor

  public MyContext() : base("MyContext")
  {
  }

  #endregion

  #region Methods

 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);
 }

  #endregion
}

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

  var users = new List<User>
  {
   new User { Name = "Sam", Login = "sam", Password = "1234567890", IsDisabled = false, Email = "sam@sam.com", FailedLoginAttempts = 0, Creator=systemUser, CreatedOn = DateTime.Today, Modifier=systemUser, ModifiedOn = DateTime.Today, IsDeleted = false },
   new User { Name = "Peter", Login = "peter", Password = "1234567890", IsDisabled = false, Email = "peter@peter.com", FailedLoginAttempts = 0, Creator=systemUser, CreatedOn = DateTime.Today, Modifier=systemUser, ModifiedOn = DateTime.Today, IsDeleted = false },
  };
  users.ForEach(s => context.Users.Add(s));
  context.SaveChanges();
    
  
 }
}    


Result in SQL Server

2017年9月28日 星期四

How to upgrade the umbraco backoffice or package involved backoffice changes under TFS control


Environment
- Umbraco version 7.x
- TFS 2010
- Ms Visual Studio 2015


Step 1
Make sure Backup whole solution and database included appData folder

Step 2
Stop the Wesite in IIS ( if the current runtime folder is binding to IIS )

Step 3 Un-blind TFS
- Open the Visual Studio Solution
- Click File > Source Control > Advanced > Change Source Control


- Save Solution and Close

Step 4 Made all folder and file under the solution writeable

Step 5 Open VS solution 

Step 6 Backup config folder (..\config)

Step 7. Install or Upgrade the package or umbracoCms

Click Yes to conflict file, let umbraco overwrite your own config file ( Caution: your own config file must be backup )


PM> update-package umbracocms
Attempting to gather dependency information for multiple packages with respect to project 'Intranet', targeting '.NETFramework,Version=v4.6.1'
Attempting to resolve dependencies for multiple packages.
Resolving actions install multiple packages
Removed package 'UmbracoCms 7.7.4' from 'packages.config'
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\applications.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ClientDependency.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\Dashboard.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineIndex.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\HealthChecks.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\log4net.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\trees.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\umbracoSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\applications.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ClientDependency.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\Dashboard.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineIndex.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\HealthChecks.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\log4net.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\trees.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\umbracoSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\applications.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ClientDependency.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\Dashboard.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineIndex.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\ExamineSettings.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\HealthChecks.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\log4net.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\trees.config' because it was modified.
Skipping 'X:\Umbraco\Trunk\Source\MySolution\MyProject\Config\umbracoSettings.config' because it was modified.
Directory 'Media' is not empty. Skipping...
Successfully uninstalled 'UmbracoCms 7.7.4' from Intranet
Removed package 'UmbracoCms.Core 7.7.4' from 'packages.config'
Successfully uninstalled 'UmbracoCms.Core 7.7.4' from Intranet
Removed package 'Examine 0.1.85' from 'packages.config'
Successfully uninstalled 'Examine 0.1.85' from Intranet
Removed package 'ImageProcessor.Web.Config 2.3.0.0' from 'packages.config'
Successfully uninstalled 'ImageProcessor.Web.Config 2.3.0.0' from Intranet
Removed package 'ImageProcessor.Web 4.8.3' from 'packages.config'
Successfully uninstalled 'ImageProcessor.Web 4.8.3' from Intranet
Removed package 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from 'packages.config'
Successfully uninstalled 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from Intranet
Removed package 'ImageProcessor 2.5.3' from 'packages.config'
Successfully uninstalled 'ImageProcessor 2.5.3' from Intranet
  GET https://api.nuget.org/v3-flatcontainer/imageprocessor/2.5.6/imageprocessor.2.5.6.nupkg
  OK https://api.nuget.org/v3-flatcontainer/imageprocessor/2.5.6/imageprocessor.2.5.6.nupkg 1531ms
Installing ImageProcessor 2.5.6.
Adding package 'ImageProcessor.2.5.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.2.5.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.2.5.6' to 'packages.config'
Successfully installed 'ImageProcessor 2.5.6' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/microsoft.io.recyclablememorystream/1.2.2/microsoft.io.recyclablememorystream.1.2.2.nupkg
  OK https://api.nuget.org/v3-flatcontainer/microsoft.io.recyclablememorystream/1.2.2/microsoft.io.recyclablememorystream.1.2.2.nupkg 1053ms
Installing Microsoft.IO.RecyclableMemoryStream 1.2.2.
Adding package 'Microsoft.IO.RecyclableMemoryStream.1.2.2' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Microsoft.IO.RecyclableMemoryStream.1.2.2' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Microsoft.IO.RecyclableMemoryStream.1.2.2' to 'packages.config'
Successfully installed 'Microsoft.IO.RecyclableMemoryStream 1.2.2' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/imageprocessor.web/4.8.7/imageprocessor.web.4.8.7.nupkg
  OK https://api.nuget.org/v3-flatcontainer/imageprocessor.web/4.8.7/imageprocessor.web.4.8.7.nupkg 861ms
Installing ImageProcessor.Web 4.8.7.
Adding package 'ImageProcessor.Web.4.8.7' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.4.8.7' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.4.8.7' to 'packages.config'
Successfully installed 'ImageProcessor.Web 4.8.7' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/imageprocessor.web.config/2.3.1/imageprocessor.web.config.2.3.1.nupkg
  OK https://api.nuget.org/v3-flatcontainer/imageprocessor.web.config/2.3.1/imageprocessor.web.config.2.3.1.nupkg 872ms
Installing ImageProcessor.Web.Config 2.3.1.
Adding package 'ImageProcessor.Web.Config.2.3.1' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.Config.2.3.1' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'ImageProcessor.Web.Config.2.3.1' to 'packages.config'
Successfully installed 'ImageProcessor.Web.Config 2.3.1' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/examine/0.1.88/examine.0.1.88.nupkg
  OK https://api.nuget.org/v3-flatcontainer/examine/0.1.88/examine.0.1.88.nupkg 863ms
Installing Examine 0.1.88.
Adding package 'Examine.0.1.88' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Examine.0.1.88' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'Examine.0.1.88' to 'packages.config'
Successfully installed 'Examine 0.1.88' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/umbracocms.core/7.7.6/umbracocms.core.7.7.6.nupkg
  OK https://api.nuget.org/v3-flatcontainer/umbracocms.core/7.7.6/umbracocms.core.7.7.6.nupkg 863ms
Installing UmbracoCms.Core 7.7.6.
Adding package 'UmbracoCms.Core.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'UmbracoCms.Core.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'UmbracoCms.Core.7.7.6' to 'packages.config'
Executing script file 'X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.Core.7.7.6\tools\install.ps1'
installPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.Core.7.7.6
toolsPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.Core.7.7.6\tools
 
projectPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\
backupPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-105604
copyLogsPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-105604\CopyLogs
umbracoBinFolder: X:\Umbraco\Trunk\Source\MySolution\MyProject\bin
Successfully installed 'UmbracoCms.Core 7.7.6' to Intranet
  GET https://api.nuget.org/v3-flatcontainer/umbracocms/7.7.6/umbracocms.7.7.6.nupkg
  OK https://api.nuget.org/v3-flatcontainer/umbracocms/7.7.6/umbracocms.7.7.6.nupkg 876ms
Installing UmbracoCms 7.7.6.
Adding package 'UmbracoCms.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Added package 'UmbracoCms.7.7.6' to folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
File Conflict
File 'Config\umbracoSettings.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\umbracoSettings.config'..
File Conflict
File 'Config\trees.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\trees.config'..
File Conflict
File 'Config\log4net.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\log4net.config'..
File Conflict
File 'Config\HealthChecks.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\HealthChecks.config'..
File Conflict
File 'Config\ExamineSettings.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\ExamineSettings.config'..
File Conflict
File 'Config\ExamineIndex.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\ExamineIndex.config'..
File Conflict
File 'Config\Dashboard.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\Dashboard.config'..
File Conflict
File 'Config\ClientDependency.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\ClientDependency.config'..
File Conflict
File 'Config\applications.config' already exists in project 'Intranet'. Do you want to overwrite it?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "N"):y
Overwriting existing file 'Config\applications.config'..
Added package 'UmbracoCms.7.7.6' to 'packages.config'
Executing script file 'X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6\tools\install.ps1'
installPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6
toolsPath: X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6\tools
 
projectPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\
backupPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-110339
copyLogsPath: X:\Umbraco\Trunk\Source\MySolution\MyProject\App_Data\NuGetBackup\20171128-110339\CopyLogs
webConfigSource: X:\Umbraco\Trunk\Source\MySolution\MyProject\Web.config
configFolder: X:\Umbraco\Trunk\Source\MySolution\MyProject\Config
Copying2 X:\Umbraco\Trunk\Source\MySolution\packages\UmbracoCms.7.7.6\UmbracoFiles\Umbraco\Views\install\* to X:\Umbraco\Trunk\Source\MySolution\MyProject\Umbraco\Views\install\
Successfully installed 'UmbracoCms 7.7.6' to Intranet
Removing package 'UmbracoCms 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'UmbracoCms 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'UmbracoCms.Core 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'UmbracoCms.Core 7.7.4' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'Examine 0.1.85' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'Examine 0.1.85' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'ImageProcessor.Web.Config 2.3.0.0' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'ImageProcessor.Web.Config 2.3.0.0' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'ImageProcessor.Web 4.8.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'ImageProcessor.Web 4.8.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'Microsoft.IO.RecyclableMemoryStream 1.2.1' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removing package 'ImageProcessor 2.5.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
Removed package 'ImageProcessor 2.5.3' from folder 'X:\Umbraco\Trunk\Source\MySolution\packages'
PM> 



Step 8 Handle conflict config file

Use WinMerge to compare config file one by one carefully, add back your own part to the umbraco one.

Step 9. After Successfully install or upgrade and tested bind to TFS again.