zoukankan      html  css  js  c++  java
  • Dapper扩展Refactored Dapper Extensions

    Refactored Dapper Extensions
    
    Making extensions for Dapper-dot-net was so fun and I needed a few more simple ones so I refactored a bit and made a few Update() and Delete() extensions as well. I’m also looking for Id-properties with the [Key] attribute on them. The class grew a bit, but it now supports the functions below. Note that this will only work for very simple objects and tables, but it might be helpful for some of you 
    
    I’m trying to follow the overall Dapper syntax as much as I can. If you done specify the table name with the input parameter, I’m using the name of the class/entity as table name, except where anonymous types are used.
    
    The object I’m using for testing
    
        public class Test
        {
            [Key]
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }
    Insert typed object
    
                    var entity = new Test() { Name = "Johan", Age = 44 };
                    connection.Insert(entity);
    Insert anonymous object
    
                    connection.Insert("insert into test", new { Name = "Johan", Age = 20 });
    Update typed object (where-clause built up from Id-properties)
    
                    var entity = new Test() { Id = 16, Name = "Johan", Age = 50 };
                    connection.Update(entity);
    Delete typed object (where-clause built up from Id-properties)
    
                    var entity = new Test() { Id = 4, Name = "Johan", Age = 44 };
                    var deletedCount = connection.Delete(entity);
    Delete anonymous object (where-clause built up from anonymous object)
    
                    var deletedCount = connection.Delete("delete from test", new { Name = "Johan" });
    The Code:
    
    public static class DapperExtensions
    {
        public static void Insert(this IDbConnection connection, object entityToInsert)
        {
            Insert(connection, null, entityToInsert);
        }
    
        public static void Insert(this IDbConnection connection, string sql, object entityToInsert)
        {
            var name = entityToInsert.GetType().Name;
            var sb = new StringBuilder(sql);
            if (sql == null)
                sb.AppendFormat("insert into {0}", name);
            sb.Append(" (");
            BuildInsertParameters(entityToInsert, sb);
            sb.Append(") values (");
            BuildInsertValues(entityToInsert, sb);
            sb.Append(")");
            connection.Execute(sb.ToString(), entityToInsert);
        }
    
        public static int Update(this IDbConnection connection, object entityToUpdate)
        {
            return Update(connection, null, entityToUpdate);
        }
    
        public static int Update(this IDbConnection connection, string sql, object entityToUpdate)
        {
            var idProps = GetIdProperties(entityToUpdate);
            if (idProps.Count() == 0)
                throw new ArgumentException("Entity must have at least one [Key] property");
    
            var name = entityToUpdate.GetType().Name;
    
            var sb = new StringBuilder(sql);
            if (sql == null)
                sb.AppendFormat("update {0}", name);
    
            sb.AppendFormat(" set ");
            BuildUpdateSet(entityToUpdate, sb);
            sb.Append(" where ");
            BuildWhere(sb, idProps.ToArray());
    
            return connection.Execute(sb.ToString(), entityToUpdate);
        }
    
        public static int Delete<T>(this IDbConnection connection, T entityToDelete)
        {
            return Delete(connection, null, entityToDelete);
        }
    
        public static int Delete<T>(this IDbConnection connection, string sql, T entityToDelete)
        {
            var idProps = typeof (T).IsAnonymousType() ? 
                GetAllProperties(entityToDelete) : 
                GetIdProperties(entityToDelete);
    
            if (idProps.Count() == 0)
                throw new ArgumentException("Entity must have at least one [Key] property");
    
            var name = entityToDelete.GetType().Name;
    
            var sb = new StringBuilder(sql);
            if (sql == null)
                sb.AppendFormat("delete from {0}", name);
    
            sb.Append(" where ");
            BuildWhere(sb, idProps);
    
            return connection.Execute(sb.ToString(), entityToDelete);
        }
    
        private static void BuildUpdateSet(object entityToUpdate, StringBuilder sb)
        {
            var nonIdProps = GetNonIdProperties(entityToUpdate).ToArray();
    
            for (var i = 0; i < nonIdProps.Length; i++)
            {
                var property = nonIdProps[i];
    
                sb.AppendFormat("{0} = @{1}", property.Name, property.Name);
                if (i < nonIdProps.Length - 1)
                    sb.AppendFormat(", ");
            }
        }
    
        private static void BuildWhere(StringBuilder sb, IEnumerable<PropertyInfo> idProps)
        {
            for (var i = 0; i < idProps.Count(); i++)
            {
                sb.AppendFormat("{0} = @{1}", idProps.ElementAt(i).Name, idProps.ElementAt(i).Name);
                if (i < idProps.Count() - 1)
                    sb.AppendFormat(" and ");
            }
        }
    
        private static void BuildInsertValues(object entityToInsert, StringBuilder sb)
        {
            var props = GetAllProperties(entityToInsert);
    
            for (var i = 0; i < props.Count(); i++)
            {
                var property = props.ElementAt(i);
                if (property.GetCustomAttributes(true).Where(a => a is KeyAttribute).Any()) continue;
                sb.AppendFormat("@{0}", property.Name);
                if (i < props.Count() - 1)
                    sb.Append(", ");
            }
        }
    
        private static void BuildInsertParameters(object entityToInsert, StringBuilder sb)
        {
            var props = GetAllProperties(entityToInsert);
    
            for (var i = 0; i < props.Count(); i++)
            {
                var property = props.ElementAt(i);
                if (property.GetCustomAttributes(true).Where(a => a is KeyAttribute).Any()) continue;
                sb.Append(property.Name);
                if (i < props.Count() - 1)
                    sb.Append(", ");
            }
        }
    
        private static IEnumerable<PropertyInfo> GetAllProperties(object entity)
        {
            return entity.GetType().GetProperties();
        }
    
        private static IEnumerable<PropertyInfo> GetNonIdProperties(object entity)
        {
            return GetAllProperties(entity).Where(p => p.GetCustomAttributes(true).Any(a => a is KeyAttribute) == false);
        }
    
        private static IEnumerable<PropertyInfo> GetIdProperties(object entity)
        {
            return GetAllProperties(entity).Where( p => p.GetCustomAttributes(true).Any(a => a is KeyAttribute));
        }
    }
    
    public static class TypeExtension
    {
        public static Boolean IsAnonymousType(this Type type)
        {
            if (type == null) return false;
    
            var hasCompilerGeneratedAttribute = type.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Count() > 0;
            var nameContainsAnonymousType = type.FullName.Contains("AnonymousType");
            var isAnonymousType = hasCompilerGeneratedAttribute && nameContainsAnonymousType;
    
            return isAnonymousType;
        }
    }
    Feel free to fork the code as much as you can, I’m too tired to stay up longer. Dapper is getting really useful 
  • 相关阅读:
    滴滴Ceph分布式存储系统优化之锁优化
    滴滴数据仓库指标体系建设实践
    滴滴AI Labs斩获国际机器翻译大赛中译英方向世界第三
    滴滴数据通道服务演进之路
    可编程网卡芯片在滴滴云网络的应用实践
    GPU虚拟机创建时间深度优化
    滴滴ElasticSearch千万级TPS写入性能翻倍技术剖析
    使用zip()并行迭代
    循环结构
    选择结构
  • 原文地址:https://www.cnblogs.com/MyFlora/p/2659850.html
Copyright © 2011-2022 走看看