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 
  • 相关阅读:
    基于WINCE嵌入式系统的FM1702的读写器(2)
    WINCE 按键驱动编写
    WinCE内存调整
    USB模块
    网络模块
    wince6.0下ov9650的图像保存
    Windows CE内存泄漏
    MPEG4解码函数
    centos 7 gitlab安装 李刚
    docker 17.12.0ce 空间大小和容器大小限制修改 李刚
  • 原文地址:https://www.cnblogs.com/MyFlora/p/2659850.html
Copyright © 2011-2022 走看看