之前翻譯了Dapper-Extensions項目首頁的readme.md,大家應該對這個類庫的使用有一些了解了吧,接下來是wiki的文檔翻譯,主要提到了AutoClassMapper、KeyTypes、Predicates System的高級用法用法。
若不熟悉Dapper及Dapper-Extensions的,請移步:
- 《Dapper的基本使用》:http://www.cnblogs.com/Sinte-Beuve/p/4231053.html
- 《Stackoverflow/dapper的Dapper-Extensions用法(一)》:http://www.cnblogs.com/Sinte-Beuve/p/4612971.html
- (擴展)《利用Dapper ORM搭建三層架構》:http://www.cnblogs.com/Sinte-Beuve/p/4230943.html
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所有的文檔了。
