FluentData官方文檔翻譯

開始

要求html

  • .NET 4.0.


支持的數據庫mysql


安裝
若是你使用 NuGet:sql

  • 搜索 FluentData並點擊安裝.

若是你沒有使用 NuGet:數據庫

  1. 下載壓縮包.
  2. 解壓縮,將dll拷貝進你的項目.
  3. 項目中添加對FluentData.dll的引用.

核心思想

DbContext
這個類是FluentData開始工做的入口點。它經過屬性定義配置,好比數據庫鏈接和數據庫操做

DbCommand
這個類負責執行數據庫操做

Events
DbContext類支持下面的事件
  • OnConnectionClosed
  • OnConnectionOpened
  • OnConnectionOpening
  • OnError
  • OnExecuted
  • OnExecuting
經過這些事件,可以實現記錄「錯誤日誌」或者記錄「查詢開始」等功能

Builders
它是提供了一個很好的fluent API,用於生成 insert, update 和delete 的SQL語句

Mapping
FluentData 可以自動映射查詢結果爲dynamic類型或者你自定義的類型

自定映射爲自定義類型(Entity):
  1. 若是你的字段不包含下標("_"),它就會自動映射到具備相同屬性名稱的屬性上。好比,字段「Name」的值會自動映射到實體的「Name」屬性上。
  2. 若是字段名稱包含下標 ("_"),他就會自動映射到名稱相近的屬性。好比,字段「Category_Name」可以自動映射到實體的「Category.Name」屬性上面
若是屬性名稱和字段名稱不匹配,你可使用SQL語法中的alias關鍵字或者建立你本身的映射方法。

自動映射到dynamic類型:
  1. 對於Dyanmic類型,每個屬性名都和字段名相同。數據庫查詢結果會自動映射到對應名稱的屬性上面。


何時須要手動釋放資源?express

  • 當使用UseTransaction或者UseSharedConnection時,須要手動釋放DbContext。
  • 若是使用UseMultiResult或者MultiResultSql時,須要手動釋放DbCommand。
  • 使用UseMultiResult時,須要手動釋放StoredProcedureBuilder。
其餘的時候,FluentData會自動釋放資源。就是說,數據庫鏈接會在執行SQL的時候打開並在執行完成之後自動關閉。

代碼實例

初始化DbContext
DbContext類實例化時須要的數據庫鏈接字符串,可以配置在*.config文件中,或者在代碼中提供。

重要的配置
  • IgnoreIfAutoMapFails - 在字段不能與屬性正確映射時,不要拋出錯誤。


建立、實例化DbContext
DbContext經過調用ConnectionStringName 方法實例化,讀取*.config file文件中的數據庫鏈接:oracle

public IDbContext Context()
{
	return new DbContext().ConnectionStringName("MyDatabase",
			new SqlServerProvider());
}


或者調用ConnectionStringName 方法實例化,直接提供數據庫鏈接字符串:app

public IDbContext Context()
{
	return new DbContext().ConnectionString(
	"Server=MyServerAddress;Database=MyDatabase;Trusted_Connection=True;", new SqlServerProvider());
}

提供器
若是你想鏈接其餘的非SqlServer的數據庫,這是很是簡單的,只須要替換上面代碼中的「new SqlServerProvider()」爲下面的數據提供器:
AccessProvider, DB2Provider, OracleProvider, MySqlProvider, PostgreSqlProvider, SqliteProvider, SqlServerCompact, SqlAzureProvider, SqlServerProvider.

查詢list集合
返回一個Dynamic集合:
List<dynamic> products = Context.Sql("select * from Product").QueryMany<dynamic>();


返回一個強類型集合:ide

List<Product> products = Context.Sql("select * from Product").QueryMany<Product>();


返回一個用戶自定義集合:ui

ProductionCollection products = Context.Sql("select * from Product").QueryMany<Product, ProductionCollection>();


返回DataTable:
請參考查詢單條數據

查詢單條數據:

返回一個Dynamic對象:spa

dynamic product = Context.Sql(@"select * from Product where ProductId = 1").QuerySingle<dynamic>();


返回一個強類型對象:

Product product = Context.Sql(@"select * from Product where ProductId = 1").QuerySingle<Product>();


返回一個DataTable:

DataTable products = Context.Sql("select * from Product").QuerySingle<DataTable>();
QueryMany<DataTable> 和 QuerySingle<DataTable>都可以返回DataTable,可是QueryMany返回的是List<DataTable>,因此建議使用QuerySingle,直接返回一個DataTable。調用QuerySingle的時候,返回的是查詢結果是全部行。

查詢scalar數據
int numberOfProducts = Context.Sql(@"select count(*) from Product").QuerySingle<int>();


查詢scalar數據集合

List<int> productIds = Context.Sql(@"select ProductId from Product").QueryMany<int>();


參數
索引參數:

dynamic products = Context.Sql(@"select * from Product where ProductId = @0 or ProductId = @1", 1, 2).QueryMany<dynamic>();


或者:

dynamic products = Context.Sql(@"select * from Product where ProductId = @0 or ProductId = @1")
			.Parameters(1, 2).QueryMany<dynamic>();


命名參數:

dynamic products = Context.Sql(@"select * from Product where ProductId = @ProductId1 or ProductId = @ProductId2")
			.Parameter("ProductId1", 1)
			.Parameter("ProductId2", 2)
			.QueryMany<dynamic>();


輸出參數:

var command = Context.Sql(@"select @ProductName = Name from Product where ProductId=1")
			.ParameterOut("ProductName", DataTypes.String, 100);
command.Execute();

string productName = command.ParameterValue<string>("ProductName");


集合參數-in查詢:

List<int> ids = new List<int>() { 1, 2, 3, 4 };
//becareful here,don't leave any whitespace around in(...) syntax.
dynamic products = Context.Sql(@"select * from Product where ProductId in(@0)", ids).QueryMany<dynamic>();


like查詢

string cens = "%abc%";
Context.Sql("select * from Product where ProductName like @0",cens);


映射
自動映射 - 實體和數據庫表一一對應:

List<Product> products = Context.Sql(@"select * from Product")
			.QueryMany<Product>();


自動映射到一個用戶自定義集合:

ProductionCollection products = Context.Sql("select * from Product").QueryMany<Product, ProductionCollection>();


自動映射 - 數據庫字段名和對象屬性名稱不一致, 使用SQL的alias關鍵字:
Weakly typed:

List<Product> products = Context.Sql(@"select p.*, c.CategoryId as Category_CategoryId, c.Name as Category_Name from Product p inner join Category c on p.CategoryId = c.CategoryId")
				.QueryMany<Product>();

上面的代碼中,p.*中的ProductId和Name字段會映射到實體的ProductId和Name屬性,Category_CategoryId和Category_Name會映射到Property.Category.Id和Property.Category.Name屬性上面。

使用Dynamic自定義映射:

List<Product> products = Context.Sql(@"select * from Product")
			.QueryMany<Product>(Custom_mapper_using_dynamic);

public void Custom_mapper_using_dynamic(Product product, dynamic row)
{
	product.ProductId = row.ProductId;
	product.Name = row.Name;
}


使用Datareader自定義映射:

List<Product> products = Context.Sql(@"select * from Product")
			.QueryMany<Product>(Custom_mapper_using_datareader);

public void Custom_mapper_using_datareader(Product product, IDataReader row)
{
	product.ProductId = row.GetInt32("ProductId");
	product.Name = row.GetString("Name");
}

若是你有一個複合類型的對象,須要手動控制對象生成,這時可使用QueryComplexMany/QueryComplexSingle方法:
var products = new List<Product>();
Context.Sql("select * from Product").QueryComplexMany<Product>(products, MapComplexProduct);

private void MapComplexProduct(IList<Product> products, IDataReader reader)
{
	var product = new Product();
	product.ProductId = reader.GetInt32("ProductId");
	product.Name = reader.GetString("Name");
	products.Add(product);
}


返回多結果集
FluentData支持返回多結果集。這個特性使你在一個數據庫鏈接中,能夠執行多條數據查詢語句。使用這個特性的時候,必定要注意資源的釋放:

using (var command = Context.MultiResultSql)
{
	List<Category> categories = command.Sql(
			@"select * from Category; select * from Product;").QueryMany<Category>();

	List<Product> products = command.QueryMany<Product>();
}

在第一次被調用時,只執行一條SQL語句。第二條SQL被執行時,FluentData知道了這是一個返回多結果集的查詢,就會調用上一條SQL生成的數據鏈接。

查詢數據和分頁
使用Select構建器,可以很容易的查詢數據和分頁:

List<Product> products = Context.Select<Product>("p.*, c.Name as Category_Name")
			       .From(@"Product p inner join Category c on c.CategoryId = p.CategoryId")
			       .Where("p.ProductId > 0 and p.Name is not null")
			       .OrderBy("p.Name")
			       .Paging(1, 10).QueryMany();

調用Paging(1, 10),前10條數據會返回

插入數據
使用 SQL:

int productId = Context.Sql(@"insert into Product(Name, CategoryId) values(@0, @1);")
			.Parameters("The Warren Buffet Way", 1)
			.ExecuteReturnLastId<int>();


使用構建器:

int productId = Context.Insert("Product")
			.Column("Name", "The Warren Buffet Way")
			.Column("CategoryId", 1)
			.ExecuteReturnLastId<int>();


使用構建器及其automapping特性:

Product product = new Product();
product.Name = "The Warren Buffet Way";
product.CategoryId = 1;

product.ProductId = Context.Insert<Product>("Product", product)
			.AutoMap(x => x.ProductId)
			.ExecuteReturnLastId<int>();

咱們將ProductId傳給了AutoMap方法,這樣,在執行時,就不會映射ProductId的值,由於ProductId是表的主鍵,且是自增字段。

更新數據
使用 SQL:

int rowsAffected = Context.Sql(@"update Product set Name = @0 where ProductId = @1")
			.Parameters("The Warren Buffet Way", 1)
			.Execute();


使用構建器:

int rowsAffected = Context.Update("Product")
			.Column("Name", "The Warren Buffet Way")
			.Where("ProductId", 1)
			.Execute();


使用構建器及其automapping特性:

Product product = Context.Sql(@"select * from Product where ProductId = 1")
			.QuerySingle<Product>();
product.Name = "The Warren Buffet Way";

int rowsAffected = Context.Update<Product>("Product", product)
			.AutoMap(x => x.ProductId)
			.Where(x => x.ProductId)
			.Execute();

咱們將ProductId傳給了AutoMap方法,這樣,在執行時,就不會映射ProductId的值,由於ProductId是表的主鍵。

新增和更新 - 通用填充方法

var product = new Product();
product.Name = "The Warren Buffet Way";
product.CategoryId = 1;

var insertBuilder = Context.Insert<Product>("Product", product).Fill(FillBuilder);

var updateBuilder = Context.Update<Product>("Product", product).Fill(FillBuilder);

public void FillBuilder(IInsertUpdateBuilder<Product> builder)
{
	builder.Column(x => x.Name);
	builder.Column(x => x.CategoryId);
}


刪除數據:
使用SQL:

int rowsAffected = Context.Sql(@"delete from Product where ProductId = 1")
			.Execute();


使用構建器:

int rowsAffected = Context.Delete("Product")
			.Where("ProductId", 1)
			.Execute();


存儲過程
使用SQL:

var rowsAffected = Context.Sql("ProductUpdate")
			.CommandType(DbCommandTypes.StoredProcedure)
			.Parameter("ProductId", 1)
			.Parameter("Name", "The Warren Buffet Way")
			.Execute();


使用構建器:

var rowsAffected = Context.StoredProcedure("ProductUpdate")
			.Parameter("Name", "The Warren Buffet Way")
			.Parameter("ProductId", 1).Execute();


使用構建器及其automapping特性:

var product = Context.Sql("select * from Product where ProductId = 1")
			.QuerySingle<Product>();

product.Name = "The Warren Buffet Way";

var rowsAffected = Context.StoredProcedure<Product>("ProductUpdate", product)
			.AutoMap(x => x.CategoryId).Execute();


使用構建器及其automapping、expressions特性:

var product = Context.Sql("select * from Product where ProductId = 1")
			.QuerySingle<Product>();
product.Name = "The Warren Buffet Way";

var rowsAffected = Context.StoredProcedure<Product>("ProductUpdate", product)
			.Parameter(x => x.ProductId)
			.Parameter(x => x.Name).Execute();


事務
FluentData支持事務。使用事務的時候,要注意將代碼包在using語句塊中,釋放資源。默認狀況下,若是發生了異常或者沒有執行Commit方法,就會回滾操做。

using (var context = Context.UseTransaction(true))
{
	context.Sql("update Product set Name = @0 where ProductId = @1")
				.Parameters("The Warren Buffet Way", 1)
				.Execute();

	context.Sql("update Product set Name = @0 where ProductId = @1")
				.Parameters("Bill Gates Bio", 2)
				.Execute();

	context.Commit();
}


實體工廠
實體工廠用於在自動映射時建立對象。若是你有一個複雜的業務模型在建立時須要作特殊處理,你可以建立你自定義的實體工廠

List<Product> products = Context.EntityFactory(new CustomEntityFactory())
			.Sql("select * from Product")
			.QueryMany<Product>();

public class CustomEntityFactory : IEntityFactory
{
	public virtual object Resolve(Type type)
	{
		return Activator.CreateInstance(type);
	}
}


示例代碼:FluentData.7z
相關文章
相關標籤/搜索