2016-07-14 87 views
1

我有一個類User,嵌套類BankDapper - 使用嵌套對象插入

class User{ 
     int Id; 
     string username; 
     Bank bank; 

    } 

    Class Bank{ 
     int id; 
     string name; 
    } 

我需要爲User創建插入函數。 Dapper有沒有辦法執行查詢並綁定嵌套對象的參數?

+0

你可以只創建一個匿名類'新{用戶ID = u.Id,UserName = u.username,BankId = u.bank.id,BankName = u.bank.name}' – juharr

+0

是的,這就是我現在正在做的事情,我想知道有沒有辦法做到這一點通過傳遞User類的一個實例 – SilentRage47

+0

也許你可以創建一個映射器來自動化它。 –

回答

4

可以使用DapperExtensions編寫自定義映射器小巧玲瓏

public sealed class UserMapper : ClassMapper<User> 
{ 
    public UserMapper() 
    { 
     Map(x => x.bank.id).Column("BankId"); 
     Map(x => x.bank.name).Column("BankName"); 

     AutoMap(); 
    } 
} 

https://github.com/tmsmith/Dapper-Extensions/wiki/Customized-mapping-for-a-class

確保您註冊包含映射器裝配:

DapperExtensions.SetMappingAssemblies(new[] { typeof(UserMapper).Assembly }); 
0

對於這樣的一個場景不只是一個User對象但是List<User>可能還需要db插入,可以考慮使用table valued parameters。對於您的問題,那就是:

  • 使用IEnumerable<User>IEnumerable<Bank>,哪怕是隻有一個對象

  • 充分利用TVP與適當的模式和columns順序相同IEnumerable collection存儲過程,否則會導致錯誤

  • 您可以使用dynamic parameters綁定參數,其中對於TVPIEnumerable可以使用擴展方法AsTableValuedParameters如果您使用anonymous type參數不是dynamic parameters,則使用Nuget中的FastMember中的ObjectReaderIEnuemrable<T>轉換爲Datatable,這對TVP是強制性的。即使自定義代碼可用於IEnuemrable<T>Datatable轉換,萬一幾列需要被省略,以下是代碼片段:


public static DataTable CreateTable<TDataTable>(this IEnumerable<TDataTable> collection) 
{ 
    // Fetch the type of List contained in the ParamValue 
    var tableType = typeof(TDataTable); 

    // Create DataTable which will contain data from List<T> 
    var dataTable = new DataTable(); 

    // Fetch the Type fields count 
    var columnCount = tableType.GetProperties().Count(); 

    var columnNameMappingDictionary = new Dictionary<string, string>(); 

    // Create DataTable Columns using table type field name and their types 
    // Traversing through Column Collection 
    for (var counter = 0; counter < columnCount; counter++) 
    { 
     var propertyInfo = tableType.GetProperties()[counter]; 

     var columnName = propertyInfo.Name; 

     columnNameMappingDictionary.Add(propertyInfo.Name, 
      propertyInfo.Name); 

     // Fetch the current type of a property and check whether its nullable type before adding a column 
     var currentType = tableType.GetProperties()[counter].PropertyType; 

     dataTable.Columns.Add(columnName, Nullable.GetUnderlyingType(currentType) ?? currentType); 
    } 

    // Return parameter with null value 
    if (collection == null) 
     return dataTable; 

    // Traverse through number of entries/rows in the List 
    foreach (var item in collection) 
    { 
     // Create a new DataRow 
     var dataRow = dataTable.NewRow(); 

     foreach (var columnName in columnNameMappingDictionary.Select(propertyinfo => propertyinfo.Value)) 
     { 
      dataRow[columnName] = item.GetType().GetProperty(columnName).GetValue(item) ?? DBNull.Value; 
     } 
     // Add Row to Table 
     dataTable.Rows.Add(dataRow); 
    } 

    return (dataTable); 
}