前一章講解了如何配置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)操作