2016-07-14 84 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); 
}