FluentData -Micro ORM with a fluent API that makes it simple to query a database
Code samples
Create and initialize a DbContext
The connection string on the DbContext class can be initialized either by giving the connection string name in the *.config file or by sending in the entire connection string.
Important configurations
- IgnoreIfAutoMapFails - Calling this prevents automapper from throwing an exception if a column cannot be mapped to a corresponding property due to a name mismatch.
Create and initialize a DbContext
The DbContext can be initialized by either calling ConnectionStringName which will read the connection string from the *.config file:
public IDbContext Context()
{
return new DbContext().ConnectionStringName("MyDatabase",
new SqlServerProvider());
}
or by calling the ConnectionString method to set the connection string explicitly:
public IDbContext Context()
{
return new DbContext().ConnectionString(
"Server=MyServerAddress;Database=MyDatabase;Trusted_Connection=True;", new SqlServerProvider());
}
Providers
If you want to work against another database than SqlServer then simply replace the new SqlServerProvider() in the sample code above with any of the following:
AccessProvider, DB2Provider, OracleProvider, MySqlProvider, PostgreSqlProvider, SqliteProvider, SqlServerCompact, SqlAzureProvider, SqlServerProvider.
Query for a list of items
Return a list of dynamic objects (new in .NET 4.0):
List<dynamic> products = Context.Sql("select * from Product").QueryMany<dynamic>();
Return a list of strongly typed objects:
List<Product> products = Context.Sql("select * from Product").QueryMany<Product>();
Return a list of strongly typed objects in a custom collection:
ProductionCollection products = Context.Sql("select * from Product").QueryMany<Product, ProductionCollection>();
Return a DataTable:
See Query for a single item.
Query for a single item
Return as a dynamic object:
dynamic product = Context.Sql(@"select * from Product
where ProductId = 1").QuerySingle<dynamic>();
Return as a strongly typed object:
Product product = Context.Sql(@"select * from Product
where ProductId = 1").QuerySingle<Product>();
Return as a DataTable:
DataTable products = Context.Sql("select * from Product").QuerySingle<DataTable>();
Both QueryMany<DataTable> and QuerySingle<DataTable> can be called to return a DataTable, but since QueryMany returns a List<DataTable> then it's more convenient to call QuerySingle which returns just DataTable. Eventhough the method is called QuerySingle then multiple rows will still be returned as part of the DataTable.
Query for a scalar value
int numberOfProducts = Context.Sql(@"select count(*)
from Product").QuerySingle<int>();
Query for a list of scalar values
List<int> productIds = Context.Sql(@"select ProductId
from Product").QueryMany<int>();
Parameters
Indexed parameters:
dynamic products = Context.Sql(@"select * from Product
where ProductId = @0 or ProductId = @1", 1, 2).QueryMany<dynamic>();
or:
dynamic products = Context.Sql(@"select * from Product
where ProductId = @0 or ProductId = @1")
.Parameters(1, 2).QueryMany<dynamic>();
Named parameters:
dynamic products = Context.Sql(@"select * from Product
where ProductId = @ProductId1 or ProductId = @ProductId2")
.Parameter("ProductId1", 1)
.Parameter("ProductId2", 2)
.QueryMany<dynamic>();
Output parameter:
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");
List of parameters - in operator:
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 operator:
string cens = "%abc%";
Context.Sql("select * from Product where ProductName like @0",cens);
Mapping
Automapping - 1:1 match between the database and the .NET object:
List<Product> products = Context.Sql(@"select *
from Product")
.QueryMany<Product>();
Automap to a custom collection:
ProductionCollection products = Context.Sql("select * from Product").QueryMany<Product, ProductionCollection>();
Automapping - Mismatch between the database and the .NET object, use the alias keyword in SQL:
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>();
Here the p.* which is ProductId and Name would be automapped to the properties Product.Name and Product.ProductId, and Category_CategoryId and Category_Name would be automapped to Product.Category.CategoryId and Product.Category.Name.
Custom mapping using 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;
}
Custom mapping using a 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");
}
Or if you have a complex entity type where you need to control how it is created then the QueryComplexMany/QueryComplexSingle can be used:
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);
}
Multiple result sets
FluentData supports multiple resultsets. This allows you to do multiple queries in a single database call. When this feature is used it's important to wrap the code inside a using statement as shown below in order to make sure that the database connection is closed.
using (var command = Context.MultiResultSql)
{
List<Category> categories = command.Sql(
@"select * from Category;
select * from Product;").QueryMany<Category>(); List<Product> products = command.QueryMany<Product>();
}
The first time the Query method is called it does a single query against the database. The second time the Query is called, FluentData already knows that it's running in a multiple result set mode, so it reuses the data retrieved from the first query.
Select data and Paging
A select builder exists to make selecting data and paging easy:
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();
By calling Paging(1, 10) then the first 10 products will be returned.
Insert data
Using SQL:
int productId = Context.Sql(@"insert into Product(Name, CategoryId)
values(@0, @1);")
.Parameters("The Warren Buffet Way", 1)
.ExecuteReturnLastId<int>();
Using a builder:
int productId = Context.Insert("Product")
.Column("Name", "The Warren Buffet Way")
.Column("CategoryId", 1)
.ExecuteReturnLastId<int>();
Using a builder with 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>();
We send in ProductId to the AutoMap method to get AutoMap to ignore and not map the ProductId since this property is an identity field where the value is generated in the database.
Update data
Using SQL:
int rowsAffected = Context.Sql(@"update Product set Name = @0
where ProductId = @1")
.Parameters("The Warren Buffet Way", 1)
.Execute();
Using a builder:
int rowsAffected = Context.Update("Product")
.Column("Name", "The Warren Buffet Way")
.Where("ProductId", 1)
.Execute();
Using a builder with 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();
We send in ProductId to the AutoMap method to get AutoMap to ignore and not map the ProductId since this is the identity field that should not get updated.
IgnoreIfAutoMapFails
When read from database,If some data columns not mappinged with entity class,by default ,will throw exception.
if you want ignore the exception, or the property not used for map data table,then you can use the IgnoreIfAutoMapFails(true),this will ignore the exception when read mapping error.
context.IgnoreIfAutoMapFails(true);
Insert and update - common Fill method
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);
}
Delete data
Using SQL:
int rowsAffected = Context.Sql(@"delete from Product
where ProductId = 1")
.Execute();
Using a builder:
int rowsAffected = Context.Delete("Product")
.Where("ProductId", 1)
.Execute();
Stored procedure
Using SQL:
var rowsAffected = Context.Sql("ProductUpdate")
.CommandType(DbCommandTypes.StoredProcedure)
.Parameter("ProductId", 1)
.Parameter("Name", "The Warren Buffet Way")
.Execute();
Using a builder:
var rowsAffected = Context.StoredProcedure("ProductUpdate")
.Parameter("Name", "The Warren Buffet Way")
.Parameter("ProductId", 1).Execute();
Using a builder with 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();
Using a builder with automapping and 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();
Transactions
FluentData supports transactions. When you use transactions its important to wrap the code inside a using statement to make sure that the database connection is closed. By default, if any exception occur or if Commit is not called then Rollback will automatically be called.
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();
}
Entity factory
The entity factory is responsible for creating object instances during automapping. If you have some complex business objects that require special actions during creation, you can create your own custom entity factory:
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);
}
}
Last edited Mar 2, 2015 at 4:36 AM by kindblad, version 52
url: http://fluentdata.codeplex.com/documentation#Events
FluentData -Micro ORM with a fluent API that makes it simple to query a database的更多相关文章
- FluentData -Micro ORM with a fluent API that makes it simple to query a database 【MYSQL】
官方地址:http://fluentdata.codeplex.com/documentation MYSQL: MySQL through the MySQL Connector .NET driv ...
- ORM系列之二:EF(4) 约定、注释、Fluent API
目录 1.前言 2.约定 2.1 主键约定 2.2 关系约定 2.3 复杂类型约定 3.数据注释 3.1 主键 3.2 必需 3.3 MaxLength和MinLength 3.4 NotMapped ...
- [大雾雾雾雾] 告别该死的 EFCore Fluent API
[EF Core Oracle 列名大小写问题] [EF Core Oracle column name case problem] [EF Core PostgreSql 列名大小写问题] [EF ...
- 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...
- EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射
I.EF里的默认映射 上篇文章演示的通过定义实体类就可以自动生成数据库,并且EF自动设置了数据库的主键.外键以及表名和字段的类型等,这就是EF里的默认映射.具体分为: 数据库映射:Code First ...
- EF:Fluent API 把一对多映射为一对一
假设有两张表:A表和B表.A表与B表在数据库中的关系是一对多,但我们需要在EF中映射为一对一. 首先在A实体类和B实体类中互相为对方增加一个实体类的属性: public A { public B B ...
- 8.2 使用Fluent API进行实体映射【Code-First系列】
现在,我们来学习怎么使用Fluent API来配置实体. 一.配置默认的数据表Schema Student实体 using System; using System.Collections.Gener ...
- 8.3 使用Fluent API进行属性映射【Code-First系列】
现在,我打算学习,怎么用Fluent API来配置领域类中的属性. using System; using System.Collections.Generic; using System.Linq; ...
- EF Fluent API上
什么是Fluent API? 官方答案:EF 中内嵌的约定将 POCO 类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方 ...
随机推荐
- Linux 内核 EISA 总线
扩展 ISA (EISA) 总线是一个对 ISA 的 32-位 扩展, 带有一个兼容的接口连接器; ISA 设备板可被插入一个 EISA 连接器. 增加的线在 ISA 接触之下被连接. 如同 PCI ...
- 面试题 —— Ajax的基本原理总结
Ajax 的全称是Asynchronous JavaScript and XML(异步的JavaScript 和 XML),其中,Asynchronous 是 异步 的意思,它有别于传统web开发中采 ...
- error:cannot load file (code:5555h);bootauto.ini
最近发现有的网友在使用Ghost XP盘安装系统的时候,选择一键ghost到C盘出现下面的错误: error:cannot load file (code:5555h);bootauto.ini(或b ...
- read、write 与recv、send区别 gethostname
recv相对于read有什么区别呢? 其实它跟read函数功能一样,都可以从套接口缓冲区sockfd中取数据到buf,但是recv仅仅只能够用于套接口IO,并不能用于文件IO以及其它的IO,而read ...
- 第三阶段:3.Web端产品设计:5.产品设计-视觉设计
视觉设计主要在表现层. 色彩心理产品经理可以也是应当掌握的.什么颜色的选择都是有理有据的. 信息清晰度. 比如这个图:当用户操作出问题,谷歌会给出问题同时给出解决方法. 视觉动物. 2/8分布原则.用 ...
- 本地项目推送到coding
当我们本地新建了一个项目,需要放到coding上维护时,按照下面步骤即可做到. 1.先在coding上新建一个项目,并完成初始化. 2.进入到本地项目的目录下 //初始化本地仓库 a:git in ...
- 专业版12.0试用,打开演示账套,提示“列名FPlatver无效”
你好,我代表研发来说明一下这个问题:一.产生的原因:由于KIS产品今年陆续都增加了应用平台,前期平台兼容性还有些问题,如果一台电脑有多个不同版本的平台,就会产生冲突,因此报错.1.可能您的机器装了多个 ...
- 0029 定位:position(相对、绝对、固定、绝对定位盒子居中、z-index、绝对定位改变display属性)
目标 理解 能说出为什么要用定位 能说出定位的4种分类 能说出四种定位的各自特点 能说出我们为什么常用子绝父相布局 应用 能写出淘宝轮播图布局 1. CSS 布局的三种机制 网页布局的核心 -- 就是 ...
- [**P2766** 最长不下降子序列问题](https://www.luogu.org/problemnew/show/P2766)
P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(dp(i)\)代表以\(i\)为起点的\(LIS\)是多少.转移太显然了 \[ dp(i)=m ...
- 初入webpack
为什么需要构建工具? 通过caniuse我们了解到 现代浏览器对es6特性的支持程度: 由于现代浏览器对es6特性的支持度并不能说太高,为了兼容所以需要进行 es6语法的转换,除了此,三大框架的语法特 ...