輕量級ORM-Fluentdata介紹

来源:http://www.cnblogs.com/xinlj/archive/2016/01/04/5097871.html
-Advertisement-
Play Games


Fluent Data 入門

由 Primates 根據互聯網資源整理FluentData 是微型 ORM(micro-ORM)家族的一名新成員,旨在比大型 ORM(full ORM)更加易用。FluentData 於本月推出,它使用 fluent API 並支持 SQL Server、SQL Azure、Oracle和 MYSQL。

FluentData 的設計者 Lars-Erik Kindblad 談到:

當前市面上的 ORM 框架,如 Entity Framework NHibernate,都過於複雜而且難於學習。此外,由於這些框架自身抽象的查詢語言以及從資料庫到.NET 對象的映射太過麻煩,導致它們生成的 SQL 都很低效。FluentData 另闢蹊徑,它是一個輕量級框架,擁有簡單的 fluent API 並且很容易學會。與其他微型 ORM(如 Dapper 和 Massive)類似,FluentData 關註性能和易用性。它允許開發人員擁有對 SQL 較多的控制,而不是依賴 ORM 進行自動生成。它不僅可以使用 SQL 來執行查詢、增添和更新操作,還可以支持使用存儲過程和事務。根據文檔描述,FluentData 可以在不改動已有結構的情況下,與任何業務對象一同工作。

以下是 FluentData 的一些其他特性:

  •  多結果集(Multiple Result Set):在一次資料庫操作下返回多個數據集;
  •  開發人員可使用強類型對象或動態對象;
  •  可為創建時需要特殊處理的複雜對象自定義實體工廠(Custom Entity Factory);
  •  具有添加其他資料庫支持的能力。

FluentData 需要 .NET 4.0,並支持 SQL Server、SQL Azure、SQL Server Compact 以及使用 .NET 驅動的 Oracle 和 MySQL。 想要瞭解進一步信息,如代碼示例和免費下載,請訪問CodePlex 站點上的 FluentData

二 創建 DbContext

初始化一個 DbContext

可以在*.config 文件中配置 connection string,將 connection string name 或者將整個 connection string作為參數傳遞給 DbContext 來創建 DbContext。

重要配置

IgnoreIfAutoMapFails – IDbContext.IgnoreIfAutoMapFails 返回一個 IDbContext,該實例中,如果自動映射失敗時是否拋出異常

  通過*.config 中配置的 ConnectionStringName 創建一個 DbContext

1: public IDbContext Context()

2: {

3:  return new DbContext().ConnectionStringName("MyDatabase",

4:    new SqlServerProvider());

5: }

  調用 DbContext 的 ConnectionString 方法顯示設置 connection string 來創建

1: public IDbContext Context()

2: {

3:  return new DbContext().ConnectionString(

4:    "Server=MyServerAddress;Database=MyDatabase;Trusted_Connection=True;", new SqlServerProvider());

5: }

  其他可以使用的 Provider

  只有通過使用不同的 Provider,就可以切換到不同類型的資料庫伺服器上,比如

  AccessProvider, DB2Provider, OracleProvider, MySqlProvider, PostgreSqlProvider, SqliteProvider,SqlServerCompact, SqlAzureProvider, SqlServerProvider。

三 查詢(Query)

返回單個對象

  返回一個 dynamic 對象

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

  返回一個強類型對象:

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

  返回一個 DataTable:

1: DataTable products = Context.Sql("select * from Product").QuerySingle<DataTable>();

其 實 QueryMany<DataTable> 和 QuerySingle<DataTable> 都 可 以 用 來 返 回 DataTable , 但 考 慮 到QueryMany<DataTable>返回的是List<DataTable>,所以使用 QuerySingle<DataTable>來返回 DataTable 更方便。

  查詢一個標量值

1: int numberOfProducts = Context.Sql(@"select count(*) from Product").QuerySingle<int>();

返回一組數據

  返回一組 dynamic 對象(new in .NET 4.0)

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

  返回一組強類型對象

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

  返回一個自定義的 Collection

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

  返回一組標量值

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

參數化查詢

  索引順序形式的參數

1: dynamic products = Context.Sql(@"select * from Product where ProductId = @0 or ProductId = @1", 1,

2).QueryMany<dynamic>();

  或者

1: dynamic products = Context.Sql(@"select * from Product where ProductId = @0 or ProductId =

@1").Parameters(1, 2).QueryMany<dynamic>();

  名字形式的參數:

1: var command = Context.Sql(@"select @ProductName = Name from Product where ProductId=1")

2:    .ParameterOut("ProductName", DataTypes.String, 100);

3: command.Execute();

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

5: List of parameters - in operator:

6: List<int> ids = new List<int>() { 1, 2, 3, 4 };

7: dynamic products = Context.Sql(@"select * from Product

8:    where ProductId in(@0)", ids).QueryMany<dynamic>();

  Output 參數:

1: dynamic products = Context.Sql(@"select * from Product

2:  where ProductId = @ProductId1 or ProductId = @ProductId2")

3:  .Parameter("ProductId1", 1)

4:  .Parameter("ProductId2", 2)

5:  .QueryMany<dynamic>();

四 映射(Mapping)

自動映射

  在資料庫對象和.Net object 自動進行1:1匹配

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

  自動映射到一個自定義的 Collection:

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

  如果資料庫欄位和 POCO 類屬性名不一致,使用 SQL 別名語法 AS:

1: List<Product> products = Context.Sql(@"select p.*,

2:  c.CategoryId as Category_CategoryId,

3:  c.Name as Category_Name

4:  from Product p

5:  inner join Category c on p.CategoryId = c.CategoryId")

6:    .QueryMany<Product>();

在這裡 p.*中的 ProductId 和 ProductName 會自動映射到 Prodoct.ProductId 和 Product.ProductName,而Category_CategoryId 和Category_Name 將 映 射 到Product.Category.CategoryId 和Product.Category.Name.

  使用 dynamic 自定義映射規則

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

2:  .QueryMany<Product>(Custom_mapper_using_dynamic);

3:

4: public void Custom_mapper_using_dynamic(Product product, dynamic row)

5: {

6:  product.ProductId = row.ProductId;

7:  product.Name = row.Name;

8: }

  使用 datareader 進行自定義映射:

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

2:.QueryMany<Product>(Custom_mapper_using_datareader);

4: public void Custom_mapper_using_datareader(Product product, IDataReader row)

5: {

6:  product.ProductId = row.GetInt32("ProductId");

7:  product.Name = row.GetString("Name");

8: }

  或者,當你需要映射到一個複合類型時,可以使用 QueryComplexMany 或者 QueryComplexSingle。

1: var products = new List<Product>();

2: Context.Sql("select * from Product").QueryComplexMany<Product>(products, MapComplexProduct);

3:

4: private void MapComplexProduct(IList<Product> products, IDataReader reader)

5: {

6:  var product = new Product();

7:  product.ProductId = reader.GetInt32("ProductId");

8:  product.Name = reader.GetString("Name");

9:  products.Add(product);

10: }

五 多結果集

FluentData 支持多結果集。也就是說,可以在一次資料庫查詢中返回多個查詢結果。使用該特性的時候,記得使用類似下麵的語句對查詢語句進行包裝。需要在查詢結束後把連接關閉。

1: using (var command = Context.MultiResultSql)

2: {

3:  List<Category> categories = command.Sql(

4:    @"select * from Category;

5:    select * from Product;").QueryMany<Category>();

6:

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

8: }

執行第一個查詢時,會從資料庫取回數據,執行第二個查詢的時候,FluentData 可以判斷出這是一個多結果集查詢,所以會直接從第一個查詢里獲取需要的數據.

六 分頁

1: List<Product> products = Context.Select<Product>("p.*, c.Name as Category_Name")

2:  .From(@"Product p

3:  inner join Category c on c.CategoryId = p.CategoryId")

4:  .Where("p.ProductId > 0 and p.Name is not null")

5:  .OrderBy("p.Name")

6:  .Paging(1, 10).QueryMany();

調用 Paging(1, 10),會返回最先檢索到的10個 Product

七 資料庫操作(Insert, Update, Delete)

插入數據

  使用 SQL 語句:

1: int productId = Context.Sql(@"insert into Product(Name, CategoryId)

2:  values(@0, @1);")

3:  .Parameters("The Warren Buffet Way", 1)

4:  .ExecuteReturnLastId<int>();

  使用 builder:

1: int productId = Context.Insert("Product")

2:  .Column("Name", "The Warren Buffet Way")

3:  .Column("CategoryId", 1)

4:  .ExecuteReturnLastId<int>();

  使用 builder,並且自動映射

1: Product product = new Product();

2: product.Name = "The Warren Buffet Way";

3: product.CategoryId = 1;

4:

5: product.ProductId = Context.Insert<Product>("Product", product)

6:  .AutoMap(x => x.ProductId)

7:  .ExecuteReturnLastId<int>();

將 ProductId 作為 AutoMap 方法的參數,是要指明 ProductId 不需要進行映射,因為它是一個資料庫自增長欄位。

更新數據

  使用 SQL 語句:

1: int rowsAffected = Context.Sql(@"update Product set Name = @0 where ProductId = @1")

2:  .Parameters("The Warren Buffet Way", 1)

3:  .Execute();

  使用 builder:

1: int rowsAffected = Context.Update("Product")

2:  .Column("Name", "The Warren Buffet Way")

3:  .Where("ProductId", 1)

4:  .Execute();

使用 builder,並且自動映射:

1: Product product = Context.Sql(@"select * from Product

2:  where ProductId = 1")

3:  .QuerySingle<Product>();

 

4: product.Name = "The Warren Buffet Way";

5:

6: int rowsAffected = Context.Update<Product>("Product", product)

7:  .AutoMap(x => x.ProductId)

8:  .Where(x => x.ProductId)

9:  .Execute();

  將 ProductId 作為 AutoMap 方法的參數,是要指明 ProductId 不需要進行映射,因為它不需要被更新。

  Insert and update - common Fill method

1: var product = new Product();

2: product.Name = "The Warren Buffet Way";

3: product.CategoryId = 1;

4:

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

6:

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

8:

9: public void FillBuilder(IInsertUpdateBuilder<Product> builder)

10: {

11:  builder.Column(x => x.Name);

12:  builder.Column(x => x.CategoryId);

13: }

14:

15: Delete

刪除數據

  使用 SQL 語句:

1: int rowsAffected = Context.Sql(@"delete from Product

2:  where ProductId = 1")

3:  .Execute();

  使用 builder:

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

2:  .Execute();

存儲過程和事物

存儲過程

  使用 SQL 語句:

1: var rowsAffected = Context.Sql("ProductUpdate")

2:  .CommandType(DbCommandTypes.StoredProcedure)

3:  .        Parameter("ProductId", 1)

4:  .Parameter("Name", "The Warren Buffet Way")

5:  .Execute();

  使用 builder:

1: var rowsAffected = Context.StoredProcedure("ProductUpdate")

2:  .Parameter("Name", "The Warren Buffet Way")

3:  .Parameter("ProductId", 1).Execute();

  使用 builder,並且自動映射

1: var product = Context.Sql("select * from Product where ProductId = 1")

2:    .QuerySingle<Product>();

3:

4: product.Name = "The Warren Buffet Way";

5:

6: var rowsAffected = Context.StoredProcedure<Product>("ProductUpdate", product)

7:  .AutoMap(x => x.CategoryId).Execute();

  使用 Lambda 表達式

1: var product = Context.Sql("select * from Product where ProductId = 1")

2:    .QuerySingle<Product>();

3: product.Name = "The Warren Buffet Way";

4:

5: var rowsAffected = Context.StoredProcedure<Product>("ProductUpdate", product)

6:  .Parameter(x => x.ProductId)

7:  .Parameter(x => x.Name).Execute();

事務

  FluentData 支持事務。如果使用事務,最好使用 using 語句將代碼包起來,已保證連接會被關閉。預設的,如果查詢過程發生異常,如事務不會被提交,會進行回滾。

1: using (var context = Context.UseTransaction(true))

2: {

3:  context.Sql("update Product set Name = @0 where ProductId = @1")

4:    .Parameters("The Warren Buffet Way", 1)

5:  .Execute();

6:

7:  context.Sql("update Product set Name = @0 where ProductId = @1")

8:    .Parameters("Bill Gates Bio", 2)

9:    .Execute();

10:

11:  context.Commit();

12: }

13:

實體工廠

實體工廠負責在自動映射的時候生成 POCO 實例。如果需要生成複雜的實例,可以自定義實體工廠:

1: List<Product> products = Context.EntityFactory(new CustomEntityFactory())

2:  .Sql("select * from Product")

3:  .QueryMany<Product>();

 

4:

5: public class CustomEntityFactory : IEntityFactory

6: {

7:  public virtual object Resolve(Type type)

8:  {

9:    return Activator.CreateInstance(type);

10:  }

11: }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題目:Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.Below is one possible representa...
  • 題目:Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.You should preserve th...
  • 一級指針與二級指針的概念和用法
  • 文章目的對於跨平臺編譯,網上有很多教程和解釋,但零零碎碎總感覺不完整,所以想集中整理一下。但跨平臺編譯是一個很寬泛的問題,如果要全部說清楚,涉及到的問題會有很多,多番查證文獻也會拖慢進度,所以決定隱藏不必要的技術細節,從“不求甚解”的角度,解釋一下跨平臺遇到的各種問題。預計隱藏的部分1.舉例子。比如...
  • 1 static void Ckeditor()2 {3 string tags = @"1234";4 //正則表達式的引擎是貪婪,只要模式允許,它將匹配儘可能多的字元。5 //如何匹配滿足條件的最短字元? 通...
  • 經過前面一段時間的努力,終於把我所知道的關於solr的內容都總結完了。前面講到了solr的安裝配置,web管理後臺的使用,solr的查詢參數和查詢語法,還說到了solr的客戶端solrnet的基本用法和Query,Facet,高亮等實際開發中的常用方法。可以說solr的相關的基礎的內容,都已經講.....
  • 封裝、繼承、多態並不是針對C#語言提出來的,他是一個在面向對象思想下產生的一個概念。所以想要弄明白封裝、繼承、多態,首先就要先瞭解面向對象概念。封裝:當我們提及面向對象的時候,這個對象怎麼來?就是通過我們人為的封裝得來。封裝就是把一些特征或功能組合到一個抽象的對象上。就比如說電腦:它的特征是有一個顯...
  • 現在有一個webform 網站 winform辦公系統,本來是相互獨立的,用的都是三層架構,dal,bll,ibll,model等等都一樣,現在想把wenform項目嵌套到winform中,就是共用dal,bll,ibll,model這些層,然而現在報錯,各種錯,例如:錯誤 157 未能找到元數據....
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...