Mvc4开发框架 -(2)Dapper 扩展 ORM 支持

 

 

开发框架搭建之初,需要有个良好的ORM。如:Entity Framework,iBatis.NET(myBatis)、PetaPoco。因为个人爱好原因,选择了轻量级的 Dapper 框架。

 

Dapper google code: http://code.google.com/p/dapper-dot-net/ 

Dapper github code: https://github.com/SamSaffron/dapper-dot-net 

 

现在对 Dapper 要做的扩展是,支持 Entity 的 CRUD ,如:

Role entity; =  new  Role();

entity.RoleId = Guid.New();
... ...
int result = entity.Insert();
result = entity.Update();
result = entity.Delete();
entity = entity.GetEntity();

 扩展预期做到以下几点:

(1) 当实体属性赋值有变化时,自动记录(比如:重新赋值主键RoleID)变更属性。

(2) 根据赋值变化记录,可以动态生成查询条件、更新字段语句。这个想法借鉴自EntityFramework。

(3) 能识别实体主键、自动生成列。在新增数据时,不插入到数据库。 

 

接下来,开始设计与开发扩展。

设计图,什么的以后再补了,先贴代码了。

 

实体模型接口,空方法接口。 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BpmExpress.Common.Models
{
     public  interface IDbEntity
    {
    } }

  

 实体模型抽象类型,基类:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Text;

namespace BpmExpress.Common.Models
{
     ///   <summary>
    
///  数据实体基类.
    
///   </summary>
    [Serializable]
     public  abstract  partial  class DbEntity : IDbEntity, INotifyPropertyChanged
    {
        [NonSerialized]
         private IList< string> _changedProperties =  null;

         public  event PropertyChangedEventHandler PropertyChanged;

         public DbEntity()
        { }

         ///   <summary>
        
///  修改的属性列表.
        
///   </summary>
         internal IList< string> ChangedProperties
        {
             get
            {
                 if (_changedProperties ==  null)
                    _changedProperties =  new List< string>();
                 return _changedProperties;
            }
        }

         protected  virtual  void OnPropertyChanged( string propertyName)
        {
             if (! this.ChangedProperties.Contains(propertyName))
            {
                 this.ChangedProperties.Add(propertyName);
            }
             if ( this.PropertyChanged !=  null)
            {
                 this.PropertyChanged.Invoke( thisnew PropertyChangedEventArgs(propertyName));
            }
        }
    }}  

 

 这个抽象类中,最主要的是 ChangedProperties,用存放实体模型变更属性。这样才能实现上面预期的 根据赋值变化记录,可以动态生成查询条件、更新字段语句。

 

 对于 Dapper 扩展如下:

 

1. 增加

  public  static  int  Insert( this  DbEntity entity, DataBase db =  null )

        {
            if (entity == null)
                return 0;
            db = GetDataBase(db);

            EntityDefinition definition = EntityDefinition.GetEntityDefinition(entity.GetType()); // 获取实体定义 
            StringBuilder parameters = new StringBuilder();
            StringBuilder values = new StringBuilder();
            IList<string> changed = null;
            if (entity != null && entity.ChangedProperties.Count > 0)
                changed = entity.ChangedProperties; // 变更属性

            foreach (var propertyName in changed)
            {
                if (definition.AutoGenerations.Contains(propertyName))
                    continue;
                parameters.AppendFormat("{0},", propertyName);
                values.AppendFormat("@{0},", propertyName);
            }
            if (parameters.Length > 1)
            {
                parameters.Length = parameters.Length - 1;
                values.Length = values.Length - 1;
            }
            string sql = string.Format("insert into {0}({1}) values ({2})", definition.TableName, parameters, values);

            int rowAffected =  db.ExecuteNonQuery(sql, entity); // Dapper方法 
            return rowAffected;
        }

 

2. 删除

 

         public  static  int Delete( this DbEntity entity, DataBase db =  null)
        {
             if (entity ==  null)
                 return  0;
            db = GetDataBase(db);

            EntityDefinition definition = EntityDefinition.GetEntityDefinition(entity.GetType());

            IList< string> changed =  null;
             if (entity !=  null && entity.ChangedProperties.Count >  0)
                changed = entity.ChangedProperties;   //  变更属性,生成删除条件

            StringBuilder  where =  new StringBuilder();
             if (changed.Count >  0)
            {
                 foreach ( var propertyName  in changed)
                {
                     where.AppendFormat( "  {0}=@{0} and ", propertyName);
                }
                 where.Length =  where.Length -  4;
            }
             else
            {
                 where.Append(definition.GetPrimaryCommand());  //  获取主键,删除
            }

             string sql =  string.Format( " delete from {0} where {1} ", definition.TableName,  where);

            Trace(sql);
             int rowAffected = db.ExecuteNonQuery(sql, entity);  //  Dapper
             return rowAffected;      }  
 

 

3. 修改

 

public  static  int Update( this DbEntity entity, DataBase db =  null)
        {
             if (entity ==  null)
                 return  0;
            db = GetDataBase(db);

            EntityDefinition definition = EntityDefinition.GetEntityDefinition(entity.GetType());

            StringBuilder parameters =  new StringBuilder();
            IList< string> changed =  null;
             if (entity !=  null && entity.ChangedProperties.Count >  0)
                changed = entity.ChangedProperties;    //  变更的字段

             if (changed ==  null || changed.Count ==  0)
                 throw  new Data.DbException( " 不存在需要更新的属性 ");

             foreach ( var propertyName  in changed)
            {
                 if (definition.AutoGenerations.Contains(propertyName))
                     continue;
                parameters.AppendFormat( " {0}=@{0}, ", propertyName);
            }
            parameters.Length = parameters.Length -  1;
//  根据主键更新
             string sql =  string.Format( " update {0} set {1} where {2} ", definition.TableName, parameters, definition.GetPrimaryCommand()); 
            Trace(sql);
             int rowAffected = db.ExecuteNonQuery(sql, entity);  //  Dapper
             return rowAffected;   }

      


4. 查询

 

 

public  static IEnumerable<T> Select<T>( this T entity,  string  orderby =  null, DataBase db =  nullwhere T : DbEntity
        {
             if (entity ==  null)
                 return  null;
            db = GetDataBase(db);
            EntityDefinition definition = EntityDefinition.GetEntityDefinition(entity.GetType());

            IList< string> changed =  null;
             if (entity !=  null && entity.ChangedProperties.Count >  0)
                changed = entity.ChangedProperties;  // 拼接查询条件的属性

             string sql =  string.Empty;
             if (! string.IsNullOrEmpty( orderby))
                 orderby =  "  order by  " +  orderby;

             if (changed !=  null && changed.Count >  0)
            { // 动态拼接查询条件 

                StringBuilder where = new StringBuilder();
                foreach (var propertyName in changed)
                {
                    where.AppendFormat(" {0}=@{0} and", propertyName);
                }
                where.Length = where.Length - 4;
                sql = string.Format("select {0} from {1} where{2}{3}", definition.GetSelectCommand(), definition.TableName, whereorderby);
            }
            else
            {   // 生成查询SQL
                sql = string.Format("select {0} from {1}{2}", definition.GetSelectCommand(), definition.TableName, orderby);
            }

            Trace(sql);
            IEnumerable<T> rows = db.ExecuteQuery<T>(sql, entity);
            return rows;
        }

 

 

 

 

 

 

你可能感兴趣的:(开发框架)