Stackoverflow/dapper的Dapper-Extensions用法(二)


之前翻譯了Dapper-Extensions項目首頁的readme.md,大家應該對這個類庫的使用有一些了解了吧,接下來是wiki的文檔翻譯,主要提到了AutoClassMapper、KeyTypes、Predicates System的高級用法用法。

若不熟悉Dapper及Dapper-Extensions的,請移步:

AutoClassMapper

在不確定的情況下Dapper Extensions使用一個默認的ClassMapper(AutoClassMapper)來處理POCO和數據表之間的映射。ClassMapper非常重要,它可以保證POCOs的純凈,不需要增加額外的attribute。你可以通過繼承ClassMapper來自定義自己的映射規則去改變Dapper Extensions的行為。(這邊我覺得文檔有些問題,應該是繼承AutoClassMapper,因為DefaultMapper是用來設置全局的映射器的而不是單表的自定義。)

DapperExtensions.DapperExtensions.DefaultMapper = typeof(MyCustomClassMapper<>);

AutoClassMapper Assumptions

默認的AutoClassMapper是建立在數據庫與POCOs之間有一定約束的條件下才可以工作的。
約定條件如下:

  • AutoClassMapper假定數據表名與POCOs名一致(Ex: Car table name and Car POCO name).。
  • 每個POCOs必須包含一個屬性名為Id或以Id結尾的。
  • 如果有多個屬性以Id結尾,Dapper Extensions會使用第一個"Id"屬性作為主鍵。
  • 如果Id屬性的類型為整形,則它的 KeyType屬性會被設成Identity。
  • 如果Id屬性的類型為GUID,則它的 KeyType屬性會被設成GUID。
  • 如果Id屬性的類型為其他類型,則它的 KeyType屬性會被設成Assigned。(此類型為用戶自定義主鍵)。

Customized PluralizedAutoClassMapper

英語有很多多元化(pluralization)的規則,PluralizedAutoClassMapper會提供給我們一些正確的多元化命名為任何可能的場景。但是仍然有很多情況,當你的數據庫表名和默認的Dapper Extensions的多元化規則不相匹配時,你可以自定義該類,注入自己的規則。

通俗的話來講,就是說數據庫表名和POCOs的命名可能會因為英文語義或者說文化等的影響而不同,這時候Dapper Extensions提供給我們PluralizedAutoClassMapper,提供一些轉換的規則。例如Person和Person。

下面的例子,使用CustomPluralizedMapper對來Person到Persons數據表進行映射。如果不重寫,PluralizedAutoClassMapper默認會把Person映射到People表。

public class CustomPluralizedMapper<T> : PluralizedAutoClassMapper<T> where T : class 
{
    protected override void Table(string tableName)
    {
        if(tableName.Equals("Person", StringComparison.CurrentCultureIgnoreCase))
        {
            TableName = "Persons";
        }

        base.Table(tableName);
    }
}

全局配置:

DapperExtensions.DapperExtensions.DefaultMapper = typeof(CustomPluralizedMapper<>);

KeyTypes

KeyType這個enum允許Dapper Extensions知道如何去映射POCOs的主鍵。當你的POCOs被Dapper Extensions檢查后,映射關系將被建立和緩存下下來。這個類型映射用於生產合適的SQL語句來進行子查詢的調用。舉個例子,在不確定的情況下,Dapper-Extensions必須知道哪一個屬性是POCOs的標識。

下列KeyTypes是可用的:

public enum KeyType
{
    NotAKey,
    Identity,
    Guid,
    Assigned
}

NotAKey

非主鍵屬性映射到該枚舉值。

Identity

任何整形的主鍵將被映射成這個枚舉值。

Guid

Guid類型的主鍵屬性被映射成這個枚舉值。這個標識會使得Dapper Extensions在數據庫執行插入命令前先生成一個新的Guid值。Dapper-Extensions生成COMB(see: GetNextGuid)

Assigned

任意非Guid和整形的主鍵將會映射到該枚舉值。這個標識會使得Dapper Extensions在數據庫執行插入命令前不會生成一個key。再者,Dapper-Extensions在插入后不會獲得任意一個鍵的值,總而言之,這個是由開發者決定的。即自定義主鍵值或者是聯合主鍵時的標識。

Predicates

謂詞系統在Dapper-Extensions中是非常容易去使用的。現在我們使用下面這個Model來展開它的用法。

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool Active { get; set; }
    public DateTime DateCreated { get; set; }
}

Simple FieldPredicate Operation

為了創建一個簡單的謂詞,我們僅僅創建一個字段謂詞並且把它傳給查詢操作。FieldPredicate需要一個一般的類型,允許使用強類型。

下面的已給例子,我們返回Active值為true的所有Persons。

Code

using (SqlConnection cn = new SqlConnection(_connectionString))
{
    cn.Open();
    var predicate = Predicates.Field<Person>(f => f.Active, Operator.Eq, true);
    IEnumerable<Person> list = cn.GetList<Person>(predicate);
    cn.Close();
}

Generated SQL

SELECT 
   [Person].[Id]
 , [Person].[FirstName]
 , [Person].[LastName]
 , [Person].[Active]
 , [Person].[DateCreated] 
FROM [Person]
WHERE ([Person].[Active] = @Active_0)

IN Clause TODO: Demonstrate that you can pass an IEnumerable as the value to acheive WHERE x IN ('a','b') functionality

Compound Predicate (Predicate Group)復合謂詞

復合謂詞謂詞可以通過謂詞組來實現。對於每個謂詞組,你必須選擇一個操作符(AND/OR),每個被添加到組中的謂詞將會被加入具體的操作。

如果每個謂詞組都實現了IPredicate,那么多謂詞可以被同時添加到一起。

下面的例子,我們建立一個通過AND操作符連接的謂詞組。

Code

using (SqlConnection cn = new SqlConnection(_connectionString))
{
    cn.Open();
    var pg = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
    pg.Predicates.Add(Predicates.Field<Person>(f => f.Active, Operator.Eq, true));
    pg.Predicates.Add(Predicates.Field<Person>(f => f.LastName, Operator.Like, "Br%"));
    IEnumerable<Person> list = cn.GetList<Person>(pg);
    cn.Close();
}

Generated SQL

SELECT 
   [Person].[Id]
 , [Person].[FirstName]
 , [Person].[LastName]
 , [Person].[Active]
 , [Person].[DateCreated] 
FROM [Person] 
WHERE (([Person].[Active] = @Active_0) 
      AND ([Person].[LastName] LIKE @LastName_1))

Multiple Compound Predicates (Predicate Group)

只要每個謂詞組都實現了IPredicate,你可以創建復雜的復合謂詞,並把它們聯合起來。

在下面的例子中,我們創建兩個謂詞組,並且把它們組合在第三個謂詞組中。

Code

using (SqlConnection cn = new SqlConnection(_connectionString))
{
    cn.Open();
    var pgMain = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List<IPredicate>() };

    var pga = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
    pga.Predicates.Add(Predicates.Field<Person>(f => f.Active, Operator.Eq, true));
    pga.Predicates.Add(Predicates.Field<Person>(f => f.LastName, Operator.Like, "Br%"));
    pgMain.Predicates.Add(pga);

    var pgb = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
    pgb.Predicates.Add(Predicates.Field<Person>(f => f.Active, Operator.Eq, false));
    pgb.Predicates.Add(Predicates.Field<Person>(f => f.FirstName, Operator.Like, "Pa%", true /* NOT */ ));
    pgMain.Predicates.Add(pgb);

    IEnumerable<Person> list = cn.GetList<Person>(pgMain);
    cn.Close();
}

Generated SQL

SELECT 
   [Person].[Id]
 , [Person].[FirstName]
 , [Person].[LastName]
 , [Person].[Active]
 , [Person].[DateCreated] 
FROM [Person] 
WHERE 
   ((([Person].[Active] = @Active_0) AND ([Person].[LastName] LIKE @LastName_1)) 
   OR (([Person].[Active] = @Active_2) AND ([Person].[FirstName] NOT LIKE @FirstName_3)))

PropertyPredicate

TODO

Exists Predicate

var subPred = Predicates.Field<User>(u => u.Email, Operator.Eq, "someone@somewhere.com");
var existsPred = Predicates.Exists<User>(subPred);
var existingUser = cn.GetList<User>(existsPred , null, tran).FirstOrDefault();

以上就是Dapper-Extensions所有的文檔了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM