开始
要求
- .NET 4.0.
- MS SQL Server using the native .NET driver.
- MS SQL Azure using the native .NET driver.
- MS Access using the native .NET driver.
- MS SQL Server Compact 4.0 through the .
- Oracle through the .
- MySQL through the .
- SQLite through the .
- PostgreSql through the provider.
- IBM DB2
安装如果你使用 NuGet:
- 搜索 FluentData并点击安装.
如果你没有使用 NuGet:
- 下载压缩包.
- 解压缩,将dll拷贝进你的项目.
- 项目中添加对FluentData.dll的引用.
核心思想
DbContext 这个类是FluentData开始工作的入口点。它通过属性定义配置,比如数据库连接和数据库操作
DbCommand
这个类负责执行数据库操作 Events
DbContext类支持下面的事件
- OnConnectionClosed
- OnConnectionOpened
- OnConnectionOpening
- OnError
- OnExecuted
- OnExecuting
通过这些事件,能够实现记录“错误日志”或者记录“查询开始”等功能 Builders
它是提供了一个很好的fluent API,用于生成 insert, update 和delete 的SQL语句 Mapping
FluentData 能够自动映射查询结果为dynamic类型或者你自定义的类型
自定映射为自定义类型(Entity):
- 如果你的字段不包含下标("_"),它就会自动映射到具有相同属性名称的属性上。比如,字段“Name”的值会自动映射到实体的“Name”属性上。
- 如果字段名称包含下标 ("_"),他就会自动映射到名称相近的属性。比如,字段“Category_Name”能够自动映射到实体的“Category.Name”属性上面。
如果属性名称和字段名称不匹配,你可以使用SQL语法中的alias关键字或者创建你自己的映射方法。
自动映射到dynamic类型:
- 对于Dyanmic类型,每一个属性名都和字段名相同。数据库查询结果会自动映射到对应名称的属性上面。
- 当使用UseTransaction或者UseSharedConnection时,需要手动释放DbContext。
- 如果使用UseMultiResult或者MultiResultSql时,需要手动释放DbCommand。
- 使用UseMultiResult时,需要手动释放StoredProcedureBuilder。
其他的时候,FluentData会自动释放资源。就是说,数据库连接会在执行SQL的时候打开并在执行完成以后自动关闭。
代码实例
初始化DbContext DbContext类实例化时需要的数据库连接字符串,能够配置在*.config文件中,或者在代码中提供。
重要的配置
- IgnoreIfAutoMapFails - 在字段不能与属性正确映射时,不要抛出错误。
创建、实例化DbContextDbContext通过调用ConnectionStringName 方法实例化,读取*.config file文件中的数据库连接:
public IDbContext Context(){ return new DbContext().ConnectionStringName("MyDatabase", new SqlServerProvider());}
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集合:
Listproducts = Context.Sql("select * from Product").QueryMany ();
Listproducts = Context.Sql("select * from Product").QueryMany ();
ProductionCollection products = Context.Sql("select * from Product").QueryMany();
dynamic product = Context.Sql(@"select * from Product where ProductId = 1").QuerySingle();
Product product = Context.Sql(@"select * from Product where ProductId = 1").QuerySingle();
DataTable products = Context.Sql("select * from Product").QuerySingle();
QueryMany<DataTable> 和 QuerySingle<DataTable>都能够返回DataTable,但是QueryMany返回的是List<DataTable>,所以建议使用QuerySingle,直接返回一个DataTable。调用QuerySingle的时候,返回的是查询结果是所有行。
查询scalar数据
int numberOfProducts = Context.Sql(@"select count(*) from Product").QuerySingle ();
List productIds = Context.Sql(@"select ProductId from Product").QueryMany ();
dynamic products = Context.Sql(@"select * from Product where ProductId = @0 or ProductId = @1", 1, 2).QueryMany();
dynamic products = Context.Sql(@"select * from Product where ProductId = @0 or ProductId = @1") .Parameters(1, 2).QueryMany();
dynamic products = Context.Sql(@"select * from Product where ProductId = @ProductId1 or ProductId = @ProductId2") .Parameter("ProductId1", 1) .Parameter("ProductId2", 2) .QueryMany();
var command = Context.Sql(@"select @ProductName = Name from Product where ProductId=1") .ParameterOut("ProductName", DataTypes.String, 100);command.Execute();string productName = command.ParameterValue("ProductName");
List ids = new List () { 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();
string cens = "%abc%";Context.Sql("select * from Product where ProductName like @0",cens);
Listproducts = Context.Sql(@"select * from Product") .QueryMany ();
ProductionCollection products = Context.Sql("select * from Product").QueryMany();
Listproducts = 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 ();
上面的代码中,p.*中的ProductId和Name字段会映射到实体的ProductId和Name属性,Category_CategoryId和Category_Name会映射到Property.Category.Id和Property.Category.Name属性上面。
使用Dynamic自定义映射:Listproducts = Context.Sql(@"select * from Product") .QueryMany (Custom_mapper_using_dynamic);public void Custom_mapper_using_dynamic(Product product, dynamic row){ product.ProductId = row.ProductId; product.Name = row.Name;}
Listproducts = Context.Sql(@"select * from Product") .QueryMany (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(products, MapComplexProduct);private void MapComplexProduct(IList products, IDataReader reader){ var product = new Product(); product.ProductId = reader.GetInt32("ProductId"); product.Name = reader.GetString("Name"); products.Add(product);}
using (var command = Context.MultiResultSql){ Listcategories = command.Sql( @"select * from Category; select * from Product;").QueryMany (); List products = command.QueryMany ();}
在第一次被调用时,只执行一条SQL语句。第二条SQL被执行时,FluentData知道了这是一个返回多结果集的查询,就会调用上一条SQL生成的数据连接。
查询数据和分页使用Select构建器,能够很容易的查询数据和分页:Listproducts = Context.Select ("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 productId = Context.Insert("Product") .Column("Name", "The Warren Buffet Way") .Column("CategoryId", 1) .ExecuteReturnLastId ();
Product product = new Product();product.Name = "The Warren Buffet Way";product.CategoryId = 1;product.ProductId = Context.Insert("Product", product) .AutoMap(x => x.ProductId) .ExecuteReturnLastId ();
我们将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();
Product product = Context.Sql(@"select * from Product where ProductId = 1") .QuerySingle();product.Name = "The Warren Buffet Way";int rowsAffected = Context.Update ("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).Fill(FillBuilder);var updateBuilder = Context.Update ("Product", product).Fill(FillBuilder);public void FillBuilder(IInsertUpdateBuilder builder){ builder.Column(x => x.Name); builder.Column(x => x.CategoryId);}
int rowsAffected = Context.Sql(@"delete from Product where ProductId = 1") .Execute();
int rowsAffected = Context.Delete("Product") .Where("ProductId", 1) .Execute();
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();
var product = Context.Sql("select * from Product where ProductId = 1") .QuerySingle();product.Name = "The Warren Buffet Way";var rowsAffected = Context.StoredProcedure ("ProductUpdate", product) .AutoMap(x => x.CategoryId).Execute();
var product = Context.Sql("select * from Product where ProductId = 1") .QuerySingle();product.Name = "The Warren Buffet Way";var rowsAffected = Context.StoredProcedure ("ProductUpdate", product) .Parameter(x => x.ProductId) .Parameter(x => x.Name).Execute();
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();}
Listproducts = Context.EntityFactory(new CustomEntityFactory()) .Sql("select * from Product") .QueryMany ();public class CustomEntityFactory : IEntityFactory{ public virtual object Resolve(Type type) { return Activator.CreateInstance(type); }} 示例代码: