阿不

不抛弃,不放弃

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  158 随笔 :: 0 文章 :: 2110 评论 :: 70 引用

【原文首次发表在:NBearLite入门二

在上一篇NBearLite使用入门中,简单了介绍了一下NBearLite基本情况。代码也是直接摘抄teddy在NBearLite源码中的测试代码,自己也没有动手去写过示例代码,也从来都没有真正使用过NBearLite的经历,所以心里难免会没底。今天晚上终于把示例代码补上了。在示例中,还包括了1.0.0.6的最新支持Save DataTable/DataRow的示例代码以及批量插入和指量指定DbCommand的例子。

应该算是昨天晚上了,teddy发布的1.0.0.6版本中,在Database里新增加了8种Save方法。都是针对DataTable/DataRow的新增行和更改行后,能够直接调用这些接口更新到数据库。提供了这些接口后,会给很多直接使用DataTable作为数据载体的朋友带来非常大的方便,先来看看它们是如何使用的:

 

SelectSqlSection sqlSection = db.Select(Northwind.Categories).Where(Northwind.Categories.CategoryID == categoryID);
DataTable dataTable = sqlSection.ToDataSet().Tables[0];
dataTable.Rows[0]["CategoryName"] = "modified";
DataRow newRow = dataTable.NewRow();
newRow["CategoryName"] = "newCategory";
dataTable.Rows.Add(newRow);
int affectRows = db.Save(sqlSection.ToDbCommand(), newRow, dataTable.Rows[0]);

在这段代码里,做了更新一条数据,和插入一条新数据的工作。使用就是这么方便,那它是如何实现的呢?其实,NBearLite只是做了非常少了事情,NBearLite是通过DbCommandBuilder来实现DataTable/DataRows的成批数据更改提交的。在ADO.NET提供的DataRow对象中,有一个属性是用来标识数据行的状态(RowState)。DbCommandBuilder就是利用这个行状态来生成插入的DbCommand,还是更新DBCommand,甚至是删除的DBCommand,进而利用DataAdapeter来执行这些生成的DBCommand,达到自动提交和更新数据的目的。

原理就是这样,使用这个接口还需注意,传入的DataRow参数,必须是已经被加入到创建它的DataTable(也就是调用dataTable.Rows.Add(newRow); ),如果一个数据行只被NewRow()出来,而没有被加到DataTable中,这时的行状态并不是Added,而是游离状态(Detached)也就无法被提交插入到数据库了。

上面提到的,DbCommandBuilder是可以生成DeleteCommand的,都就意味着,使用Database的Save接口也是可以实现数据行删除的,要将DataTable中的某一行删除,必须调用DataRow的Delete方法,而不是调用DataTable.Rows的Remove方法,这个方法纯粹就是集合删除项的意义了。

在例子中,还提供了成批插入数据和成批执行DbCommand的代码。成批插入数据有两种重载方法,带事务和不带事务。

public int ExecuteBatchInsert(string tableName, string[] columnNames, DbType[] columnTypes, object[][] rows,  int batchSize, DbTransaction tran)
public int ExecuteBatchInsert(string tableName, string[] columnNames, DbType[] columnTypes, object[][] rows, int batchSize)

前几个参数都不难理解,就rows这个参数会比较麻烦,它是一个二维数据。外维表示记录的数据,内维表示的是每个字段的值。估计很多人跟我一样,平常不怎么操作二维数组,(维护的关系),所以我个人认为这个接口的友好性方面还有待提高。并且这个接口的运行结果与目标值有一定差距,可能目前还存一些BUG。

另一种批处理是成批执行DBCommand,最大的目的就是为了能减少与数据库的连接次数(就跟团购一样,大家都是为了省钱)。大家都知道,数据库操作其实最费时间的是打开和关闭数据库连接,尽管在ADO.NET中,已经提供了连接池来解决这个问题,但是数据库连接毕竟是有限的。如果能让一些具有相同行为的DBCommand只用一次连接,那无疑可以大大提高程序的性能。NBearLite的成批执行DBCommand功能就是为了能过简单的接口来支持这一种行为。要使用Batch Command,首先要调用:

db.BeginBatchConnection(3);

参数指定了多少个Command执行一次。

接下来的就跟执行普通的DBCommand没什么两样:

db.ExecuteNonQuery(db.Insert(Northwind.Categories).AddColumn(Northwind.Categories.CategoryName, "comand" + i.ToString()).ToDbCommand());

成批执行完后要调用db.EndBatchConnection();来结束这一次的团购。

从接口的实现上,只要我们打开了批处理的选项后。不管是有没有返回的执行接口ExecuteDataSet/ExecuteScalar/ExecuteNonQuery/ExecuteReader 都会一视同仁,成批处理。从现实的角度来看,除了插入记录外,有返回数据的,我们一般都会要求马上返回数据库,而此时如果成批了,就不会马上返回数据了。并且就算有返回了,你也不知道用什么,在哪里去接收。因此除了ExecuteNonQuery有批处理的必要外,其它的接口不应该这样去做。

本篇完。

相关文章:

NBearLite入门二

阿不 http://hjf1223.cnblogs.com
posted on 2007-07-29 03:00 阿不 阅读(2990) 评论(6)  编辑 收藏 所属分类: NBear

评论

学习ing
  回复  引用    

关于ExecuteBatchInsert的介绍有一些错误:
首先,这个方法无需搭配BeginBatchConnection一起使用,而可以直接使用。
其次,这个方法的意义在于能够将超大数据量的Insert(插入的记录数几万甚至几十万)操作,性能提高N个数量级,但是只能用于SQL Server数据库。

更多介绍,请参考:http://www.cnblogs.com/teddyma/archive/2007/07/29/835412.html
  回复  引用  查看    

#3楼 [楼主] 2007-07-29 15:50 阿不      
@Teddy's Knowledge Base
可能是我上面的段落没有分得很清楚,ExecuteBatchInsert是用于成批插入数据的接口,它并不需要其它方法的支持,而下面的需要调用BeginBatchConnection的是成批执行DBCommand。
  回复  引用  查看    

@阿不
是我没看清楚:)
ExecuteBatchInsert一般不需要使用,只有在超大数据量插入时才需要。
二维数组应该像这样定义:
int ret = database.ExecuteBatchInsert(
"Categories",
new string[] { "CategoryName", "Picture" },
new DbType[] { DbType.String, DbType.Binary },
new object[][] {
new object[] { "testtest", new byte[5] { 1, 50, 100, 150, 200 } },
new object[] { "testtest", new byte[5] },
new object[] { "testtest", new byte[5] }
},
2);

  回复  引用  查看    

#5楼  2007-09-25 17:20       
理论 <---------
---------> 实际


  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-11-27 09:00 编辑过


相关链接: