FluentData官方文档翻译

开始

要求

  • .NET 4.0.

支持的数据库

安装
如果你使用 NuGet:

  • 搜索 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类型,每一个属性名都和字段名相同。数据库查询结果会自动映射到对应名称的属性上面。

什么时候需要手动释放资源?

  • 当使用UseTransaction或者UseSharedConnection时,需要手动释放DbContext。
  • 如果使用UseMultiResult或者MultiResultSql时,需要手动释放DbCommand。
  • 使用UseMultiResult时,需要手动释放StoredProcedureBuilder。

其他的时候,FluentData会自动释放资源。就是说,数据库连接会在执行SQL的时候打开并在执行完成以后自动关闭。

代码实例

初始化DbContext
DbContext类实例化时需要的数据库连接字符串,能够配置在*.config文件中,或者在代码中提供。

重要的配置

  • IgnoreIfAutoMapFails - 在字段不能与属性正确映射时,不要抛出错误。

创建、实例化DbContext
DbContext通过调用ConnectionStringName 方法实例化,读取*.config file文件中的数据库连接:

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

或者调用ConnectionStringName 方法实例化,直接提供数据库连接字符串:

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>();

返回一个强类型集合:

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

返回一个用户自定义集合:

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

返回DataTable:
请参考查询单条数据

查询单条数据:

返回一个Dynamic对象:

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);
	}
}
时间: 2024-11-26 05:53:04

FluentData官方文档翻译的相关文章

Swift 集合类型(Collection Type) 之 字典(dictionary)(官方文档翻译及总结)

Swift语言提供经典的数组和字典两种集合类型来存储集合数据.数组和字典中存储的数据值类型必须明确.这意味着我们不能把不正确的数据类型插入其中.Swift对显式类型集合的使用确保了我们的代码对工作所需要的类型非常清楚.也让我们在开发中可以早早的找到任何的类型不匹配错误.如果你用变量(var)创建的集合,这些集合就是可变的(增删改).如果用常理创建的,这些集合是不能被操作的. 注意: 如果集合的元素是不变的,那就将集合声明为常量.这样Swift编译器能对你创建的集合做性能优化. 1. 数组(arr

NServiceBus官方文档翻译(一)NServiceBus 概况

NServiceBus 概况 NServiceBus 被设计用来组合面向业务的服务,它并不是用来替代诸如 WCF 一类的RPC技术. NServiceBus 不只包含通信模块,像其他成熟的SOA和DDD项目一样,它使用了多种组合的方法和技术. 本篇文章探讨了 NServiceBus 和微软相关产品的相似点和不同点. 相比 BizTalk 更接近 WCF 当人们听到“服务总线”这个名词时,一般会描绘出如上图所示的画面,像 BizTalk 一样所有的通信都经过一个中央结点.这实际上描述的是一个代理的

Python3.2官方文档翻译--标准库概览(一)

7.1 操作系统接口 Os模块提供主要许多与操作系统交互的函数. >>> import os >>> os.getcwd() # Return the current working directory 'C:\\Python31' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # R

Alljoyn瘦客户端库介绍(官方文档翻译)

Alljoyn瘦客户端库介绍(1) 1.简介 本文档对AllJoynTM瘦客户端的核心库文件(AJTCL)进行了详尽的介绍.本文档介绍了系统整体架构,AllJoyn框架结构,并着重于介绍如何将嵌入式设备加入AllJoyn系统整体架构中.1.1目的 本文档介绍了如何使一个受限于功耗.计算能力和内存的设备(嵌入式设备)加入AllJoyn分布式系统.具体而言,本文档包括了对AllJoyn面向嵌入式系统的方面的介绍,并着重描述了基于AllJoyn的系统的各个组件是如何与嵌入式设备协作以构建一个基于接近式

Oracle 12c 12.1.0.1.0管理控制文件官方文档翻译说明

Link: http://download.csdn.net/detail/rlhua/7718571 官方Link: http://docs.oracle.com/database/121/ADMIN/control.htm#ADMIN006 版本: [email protected]>select * from v$version; BANNER                                                                          

官方文档翻译:Innodb的锁

InnoDB Record, Gap, and Next-Key Locks 考虑到翻译准确性,对于某些特殊名称不做翻译,以免误导: InnoDB has several types of record-level locks including record locks, gap locks, and next-key locks. innodb 有几种行锁类型,包括,record locks(记录锁),gap locks(间隙锁),and next-key locks(组合). Record

Aircrack-ng官方文档翻译[中英对照]---Airmon-ng

Aircrack-ng官方文档翻译---Airmon-ng Description[简介] This script can be used to enable monitor mode on wireless interfaces. It may also be used to go back from monitor mode to managed mode. Entering the airmon-ng command without parameters will show the int

Aircrack-ng官方文档翻译[中英对照]---Airdecap-ng

Aircrack-ng官方文档翻译---Airdecap-ng Description[简介] With airdecap-ng you can decrypt WEP/WPA/WPA2 capture files. As well, it can also be used to strip the wireless headers from an unencrypted wireless capture. It outputs a new file ending with ”-dec.cap”

Swift语言官方文档翻译(2)

A Swift Tour 按照惯例,我们一般学习一个新语言的时候,我们都习惯性的在屏幕上打印"Hello, World",在Swift中,你可以用如下一个单独语句实现 println("Hello,World") 如果你用C或者OC写过程序,那么上面的语句对于你来说是很熟悉的.在Swift中,这一行代码就是一个完整的程序,你不需要为了类似I/O或者String handling去导入一些jar包.全局变量将作为一个程序的入口点,所以你不需要main函数,你也不需要在