码迷,mamicode.com
首页 > 移动开发 > 详细

做自己的ORMapping Framework ---- 第七讲 开始ORMapping之旅,ORMapping 中command怎么生成呢

时间:2015-11-29 21:06:10      阅读:363      评论:0      收藏:0      [点我收藏+]

标签:

上篇介绍了ORMapping的一个大体结构,看起来很简单,基本没有什么复杂的设计模式之说,关于接口类的实现与MEF的管理在上篇都介绍过,这篇就开始介绍ORMapping中的细节点了,当然还是围绕对数据库的操作(增删查改)来讲,我这就只介绍Insert command吧,其它的都一样。

 

有朋友就会问既然是ORMapping,那肯定得有一套完整的映射关于与操作逻辑,关于映射关系的介绍之前都简单介绍过了,比较抽象,现在在这里就以怎样生成Insert Command来介绍ORMapping的核心部分。

 

在IORMapper的接口中我定义了一个Insert方法,从名称上来看,当然是作数据库的插入数据来用的。

 

接下来我会在ORMapper类中实现该方法:

public void Insert<T>(T obj)
{

}

我们既然想作一个数据库的插入操作,那我们总会有一个sqlconnection 和一个sqlcommand, 当然这不是主要的,主要的就是sqlcommand里的commandText,这个怎么来呢?这就涉及到我之前定义的Model结构和那些Attribute,不明白的可以看前面几篇里有介绍。

 

我在这就贴上我完整的Inter方法:

 

public void Insert<T>(T obj)
{
  using (IDbConnection conn = NewConnection())     // 这里有个自定义的NewConnection的方法,我就不写了,你们按照自己的需求实现
  {
    try
      {
        conn.Open();
      }
    catch (SqlException sqlEx)
    {
      throw new DbConnectionException(conn.Database, sqlEx.Message, sqlEx);
    }

    var InsertCMD = GetInsertCommands(obj, conn);            //大家可能会注意到这里有个方法,这就是去生成sqlcommand的,下面我会详细说到
    foreach (var command in InsertCMD)
    {
      using (command)
        {
          command.ExecuteNonQuery();
        }
    }
}

下面就介绍我们怎么去生成这个sqlcommand,这里我定义一些重载的GetInsertCommands方法

public List<IDbCommand> GetInsertCommands<T>(T obj, IDbConnection connection)
{
  return GetInsertCommands(obj, ColumnCollectionInfo.GetInfo(obj.GetType()), connection);
}

private List<IDbCommand> GetInsertCommands(Object obj, ColumnCollectionInfo dataInfo, IDbConnection connection)
{
  List<IDbCommand> result = new List<IDbCommand>();

  if (dataInfo.BaseInfo != null)
  {
    result.AddRange(GetInsertCommands(obj, dataInfo.BaseInfo, connection));        //这里是添加Model中基类里的数据插入操作,如果你对Model结构由疑问可以随时联系我和我交流,这边我可能不再作深入补充
  }


  if (!string.IsNullOrEmpty(dataInfo.Name))               //这里生成的是当然Table的插入的command
  {
    IDbCommand command = connection.CreateCommand();
    command.CommandText = GetInsertStatement(obj, dataInfo, command);
    result.Add(command);
  }


  var manyToManyInfos = dataInfo.Collections.Values.Cast<CollectionInfo>().Where(t => t.CollectionType == CollectionType.ManyToMany);   //这边是生成ManyToMany的关系数据的中间表数据插入Command
  foreach (CollectionInfo info in manyToManyInfos)
  {
    result.AddRange(GetInsertCommands(obj, dataInfo, info, connection));
  }

  return result;
}

private List<IDbCommand> GetInsertCommands(Object obj, ColumnCollectionInfo dataInfo, CollectionInfo collectionInfo, IDbConnection connection)
{
  List<IDbCommand> result = new List<IDbCommand>();

  IEnumerable targets = collectionInfo.GetValue(obj);
  if (targets != null)
  {
    foreach (var target in targets)
    {
      IDbCommand command = connection.CreateCommand();
      command.CommandText = GetInsertStatement(obj, target, dataInfo, collectionInfo, command);
      result.Add(command);
    }
  }

return result;
}

 

private string GetInsertStatement(Object src, Object target, ColumnCollectionInfo srcDataInfo, CollectionInfo collectionInfo, IDbCommand command)
{
  var targetDataInfo = ColumnCollectionInfo.GetInfo(target.GetType());

  int index = 0;
  List<string> values = new List<string>();
  foreach (ColumnInfo column in srcDataInfo.PrimaryKeys.Values)
  {
    string parameterName = string.Format(UpdateSqlValueParameter, index++);
    values.Add(parameterName);
    AddParameter(column, parameterName, column.GetValue(src), command);
  }
  foreach (ColumnInfo column in targetDataInfo.PrimaryKeys.Values)
  {
    string parameterName = string.Format(UpdateSqlValueParameter, index++);
    values.Add(parameterName);
    AddParameter(column, parameterName, column.GetValue(target), command);
  }

  return string.Format(InsertSql,GetTableName(collectionInfo.IntermediateTableName),collectionInfo.MapSourceKey + Comma + collectionInfo.MapTargetKey,string.Join(Comma, values));
}

private string GetInsertStatement(Object obj, ColumnCollectionInfo dataInfo, IDbCommand command)
{
  int index = 0;
  List<string> values = new List<string>();
  foreach (ColumnInfo column in dataInfo.PrimaryKeys.Values)
  {
    string parameterName = string.Format(UpdateSqlValueParameter, index++);
    values.Add(parameterName);
    AddParameter(column, parameterName, column.GetValue(obj), command);
  }
  foreach (ColumnInfo column in dataInfo.Columns.Values)
  {
    if (!column.ReadOnly)
    {
      string parameterName = string.Format(UpdateSqlValueParameter, index++);
      values.Add(parameterName);
      AddParameter(column, parameterName, column.GetValue(obj), command);
    }
  }

return string.Format(InsertSql, GetTableName(dataInfo.Name), dataInfo.GetSelectOrInsertColumns(Comma, true, Dot, LeftSquare, RightSquare, true), string.Join(Comma, values));
}

这三个方法估计你们看起来会很有疑问,这里面怎么会有一些不知道的dataInfo的一些东西,看了前面的朋友也就会发现,这里就开始用到了我们在之前定义的很多Attribute,

这些东西我本来想放在介绍这个之前来介绍的,我觉得先介绍Command的生成过程再来介绍数据库信息的获取这样会更明了,容易理解一点。下篇我会介绍那些关于数据库结构的DataInfo是怎样从Model中获取。

 

代码看起来可能会有些头晕,细心的朋友我相信会有收获的,这里我就不把我的源代码贴出来,我觉得这样的意义不大,有什么疑问随时可以和我联系,微信号:hwy425

做自己的ORMapping Framework ---- 第七讲 开始ORMapping之旅,ORMapping 中command怎么生成呢

标签:

原文地址:http://www.cnblogs.com/hwy425/p/5005290.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!