Dapper – 使用嵌套对象插入
我有一个具有嵌套类Bank
的类User
。
class User{ int Id; string username; Bank bank; } Class Bank{ int id; string name; }
我需要为User
创建一个Insert函数。 在Dapper
是否有一种方法可以执行查询并从嵌套的对象中绑定参数?
您可以使用DapperExtensions为Dapper编写自定义映射器:
public sealed class UserMapper : ClassMapper { 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 });
对于不仅仅是User
对象而是List
可能还需要db插入的情况,您可以考虑使用table valued parameters
。 对于你的问题,它将是:
-
使用
IEnumerable
和IEnumerable
,即使它只是一个对象 -
使用适当的模式和相同的
columns
顺序使TVP
与存储过程的IEnumerable collection
相同,否则会导致错误 -
您可以使用
dynamic parameters
来绑定参数,对于TVP
,可以使用扩展方法AsTableValuedParameters
提供IEnumerable
,以防您使用anonymous type
参数而不是dynamic parameters
,然后使用FastMember
中FastMember的ObjectReader
将IEnuemrable
转换为Datatable
,这对TVP是强制性的。 甚至自定义代码也可以用于IEnuemrable
到Datatable
转换,如果需要省略几列,下面是代码片段:
public static DataTable CreateTable(this IEnumerable collection) { // Fetch the type of List contained in the ParamValue var tableType = typeof(TDataTable); // Create DataTable which will contain data from List var dataTable = new DataTable(); // Fetch the Type fields count var columnCount = tableType.GetProperties().Count(); var columnNameMappingDictionary = new Dictionary(); // 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); }