zoukankan      html  css  js  c++  java
  • 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);
    	}
    }


    示例代码:FluentData.7z
  • 相关阅读:
    2017D 方格分割
    2017B 等差素数列
    完全平方数
    K-th Number(二分答案+尺取法判断)
    cf634div3
    performSelector: 与 dispatch_time 异同
    UIButton 的属性与方法
    Node.js 学习笔记三
    [2019杭电多校第一场][hdu6578]Blank(dp)
    [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)
  • 原文地址:https://www.cnblogs.com/animal/p/4056891.html
Copyright © 2011-2022 走看看