程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> MySoft.Data從入門到精通系列(四)【數據插入】

MySoft.Data從入門到精通系列(四)【數據插入】

編輯:關於.NET

前一章講解了如何配置DbSession,本章重點講解利用MySoft.Data進行數據的插入操作

這裡先引用一下上一章的DbSession的配置代碼

DbSession配置
/// <summary>
/// 數據庫訪問類
/// </summary>
public static class DataAccess
{
/// <summary>
/// 通過配置節來實例化DbSession
/// </summary>
public static readonly DbSession DefaultSession = new DbSession("DataExample");

/// <summary>
/// 通過自定義類來實例化DbSession
/// </summary>
public static readonly DataExample ExampleSession = new DataExample();

}

/// <summary>
/// DataExample會話類
/// </summary>
public class DataExample : DbSession
{
public DataExample()
: base("DataExample")
{
#if DEBUG
this.RegisterSqlLogger(log =>
{
System.IO.File.WriteAllText("c:\\log.txt", log);
});
#endif
}

/// <summary>
/// 插入實體
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="item"></param>
/// <returns></returns>
public int Insert<T>(T item) where T : Entity
{
item.Detach();
return base.Save(item);
}

/// <summary>
/// 更新實體
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="item"></param>
/// <returns></returns>
public int Update<T>(T item) where T : Entity
{
item.Attach();
return base.Save(item);
}
}

針對上一節DbSession的配置,可以看到,這裡對DataExample類擴展了兩個方法,而在我的組件內部並沒有Insert<T> (T item)與Update<T>(T item)方法,而是將其合並到了一個方法Save<T>(T item),外部通過item.Attach()與item.Detach()來改變實體的狀態。

注:item.Attach()與item.Detach()方法還有更多強大的用法,下面會重點講到!

也許有人會覺得合並在一起很難區分插入與修改,應該直接用方法名來區分比較好,當然OK,直接在這裡加上兩個方法即可,還可以擴展出更多的方法來適應你項目開發的需求,比如你完全可以擴展出一個保存多個對象的方法,如下:

一次插入多條數據的擴展

/// <summary>
/// 一次插入多條數據
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items"></param>
/// <returns></returns>
public int Insert<T>(IList<T> items) where T : Entity
{
int ret = 0;
foreach (T item in items)
{
ret += Insert(item);
}
return ret;
}

用方法名來區分固然也是好的,但如果需要保存一個實體列表,而這個列表中的實體有些是需要插入的,有些是需要更新的,你該如何處理,只有一種辦法,把列表拆分為兩個,分別來進行插入與更新。

而使用一個方法Save<T>(T item)可以很方便解決這個問題,在外部將需要插入的方法調用item.Detach(),需要更新的實體調用item.Attach()即可,然後一次傳入內部進行操作,還可以為每個實體設置插入的字段或更新的字段!這樣是否使用上更優雅一些呢,如下:

Detach()方法的簡單應用

Products product = new Products()
{
ProductName = "測試產品1"
};
DataAccess.ExampleSession.Save(product);
product.Detach(Products._.UnitPrice);
DataAccess.ExampleSession.Save(product);

如果數據庫中的某些字段有默認值,比如日期字段需要保存為getdate(),就可以通過Detach()方法將其字段移除而不進行插入!

好了,DbSession的方法擴展和簡單應用就講到這裡,下面開始講解如何使用DbSession來插入數據,領略MySoft.Data帶給你強大的功能體驗與快速開發的便捷吧!

以下操作都以數據庫Northwind為例。

一、強類型數據插入

准備工作:

新建一個MySoftExample.DataEntity的項目,使用工具將Northwind中的所有表生成實體,生成的結果如圖,生成時將命名空間也設置為MySoftExample.DataEntity。

生成以上實體項目後,再新建一個MySoftExample.Web項目,將MySoftExample.DataEntity項目添加到當前項目的引用中,下面就可以通過生成的實體進行數據的操作了。

下面的操作以Products實體為例進行操作:

1、單個實體數據插入

插入單個對象

//實例化一個Products對象
Products product = new Products()
{
ProductName = "測試產品1"
};
//插入單個對象
DataAccess.ExampleSession.Save(product);

2、批量實體數據插入

插入一組對象

//實例化一組Products對象
List<Products> list = new List<Products>();
for (int index = 0; index < 10; index++)
{
list.Add(new Products()
{
ProductName = "測試產品" + index
});
}
//批量保存數據
DbBatch batch = DataAccess.ExampleSession.BeginBatch(10);
list.ForEach(item =>
{
batch.Save(item);
});
batch.Process();

3、帶事務單個實體插入(MySoft.Data內置實現DbTrans)

插入單個對象(內置事務) 

//實例化一個Products對象
Products product = new Products()
{
ProductName = "測試產品1"
};
//使用事務進行數據插入
using (DbTrans trans = DataAccess.ExampleSession.BeginTrans())
{
try
{
trans.Save(product);
trans.Commit();
}
catch
{
trans.Rollback();
}
}

4、帶事務批量實體插入(MySoft.Data內置實現DbTrans)

插入一組對象(內置事務)

//實例化一組Products對象
List<Products> list = new List<Products>();
for (int index = 0; index < 10; index++)
{
list.Add(new Products()
{
ProductName = "測試產品" + index
});
}
//使用事務進行批量數據插入
using (DbTrans trans = DataAccess.ExampleSession.BeginTrans())
{
try
{
DbBatch batch = trans.BeginBatch(10);
list.ForEach(item =>
{
batch.Save(item);
});
batch.Process();
trans.Commit();
}
catch
{
trans.Rollback();
}
}

5、創建外部數據庫鏈接方式插入

插入單個對象(外部鏈接) 

//實例化一個Products對象
Products product = new Products()
{
ProductName = "測試產品1"
};
using (System.Data.Common.DbConnection conn = DataAccess.ExampleSession.CreateConnection())
{
//插入單個對象
DataAccess.ExampleSession.SetConnection(conn).Save(product);
}

注:批量插入可以采用同樣的方法處理!

6、創建外部數據庫事務方式插入

插入單個對象(外部事務)  

//實例化一個Products對象
Products product = new Products()
{
ProductName = "測試產品1"
};
using (System.Data.Common.DbTransaction trans = DataAccess.ExampleSession.BeginTransaction())
{
try
{
//插入單個對象
DataAccess.ExampleSession.SetTransaction(trans).Save(product);
trans.Commit();
}
catch
{
trans.Rollback();
}
}

注:批量插入可以采用同樣的方法處理!

item.Detach()方法的高級用法

1、指定某些字段使用數據默認值(不改變原有對象傳入的狀態)

//插入時排除某些字段
Detach(params Field[] removeFields);
//字段CategoryID不進行插入操作
product.Detach(Products._.CategoryID);
//ExcludeField插入時包括的字段
//調用Field.All或Products._.All的Remove方法排除插入的字段可以返回ExcludeField
//也就是說Detach會排除除Remove以外的所有字段
Detach(ExcludeField field); 
//只插入ProductName字段
product.Detach(Field.All.Remove(Products._.ProductName));

說明一下:

不改變原有對象的傳狀態是指,假如product對象已經在外面調用過如:

在之前調用了product.Detach(Product._.SupplierID);

此處再次調用會在原有的基礎上再排除CategoryID,相當於SupplierID與CategoryID都不進行插入操作,而以下DetachAll()方法則是清除之前所有的狀態,再進行當前的處理。

2、指定某些字段使用數據默認值(改變原有對象傳入的狀態)

//插入時排除某些字段
DetachAll(params Field[] removeFields);
//字段CategoryID不進行插入操作
product.DetachAll(Products._.CategoryID);
//ExcludeField插入時包括的字段
//調用Field.All或Products._.All的Remove方法排除插入的字段可以返回ExcludeField
//也就是說DetachAll會排除除Remove以外的所有字段
DetachAll(ExcludeField field); 
//只插入ProductName字段
product.DetachAll(Field.All.Remove(Products._.ProductName));

InsertOrUpdate方法的使用

當用戶不知道當前實體是否在數據庫中存在時,可以使用此方法。

內部將會根據主鍵去判斷此實體在數據庫中是否存在,然後再自動調用相應的方法來進行處理。

Products product = new Products()
{
ProductID = 1,
ProductName = "測試產品"
};
DataAccess.ExampleSession.InsertOrUpdate(product);

當然數據插入操作還有其它的方式(自己可以慢慢研究):

DataAccess.ExampleSession.Insert<Products>(
new Field[] { Products._.ProductName },
new object[] { "測試產品" });
int productID;
DataAccess.ExampleSession.Insert<Products, int>(
new Field[] { Products._.ProductName },
new object[] { "測試產品" }, out productID);

二、InsertCreator數據插入

通過插入創建器同樣也可以達到上面的效果,也可以進行泛型方式進行數據插入,一般情況下創建器用於沒有建立對象實體時直接對表和字段的操作。

1、通過實體插入實體

InsertCreator ic = InsertCreator.NewCreator()
.From<Products>()
.SetEntity<Products>(product);
DataAccess.ExampleSession.Excute(ic);

2、通過字符串表與字段插入數據

InsertCreator ic = InsertCreator.NewCreator()
.From("Products")
.AddInsert("ProductName", "測試產品");
DataAccess.ExampleSession.Excute(ic);

3、通過字符串表與字段插入數據並返回標識列值

InsertCreator ic = InsertCreator.NewCreator()
.From("Products")
.AddInsert("ProductName", "測試產品")
.SetIdentityField("ProductID");
int productID;
DataAccess.ExampleSession.Excute(ic, out productID);

以上通過創建器的方式同樣可以用事務來操作 trans.Excute(ic);

這裡只是簡單的介紹了一下,還有更多的功能需要用戶使用時才能體會到。

數據的插入操作就講解到這裡,下一章將講解數據的修改(Update)操作

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved