使用Dapper,我想实现一个接受IEnumberable类型为的对象的方法User。现在,User看起来如下:
IEnumberable
User
public class User { public int UserId { get; internal set; } public DateTime DateCreated { get; internal set; } public DateTime DateChanged { get; internal set; } public string Username { get; set; } }
这里的要点是UserId,DateCreated并且DateChanged永远都不能通过object设置,因此不能通过internal关键字设置。相反,数据库将填充这些值。
UserId
DateCreated
DateChanged
internal
因为因此将对象作为插入操作的一部分进行了修改,所以我想返回另一个IEnumerable类型的对象,User但这一次填充了相应的属性。
IEnumerable
最近,我意识到我可以让Dapper遍历User对象,IEnumerable如下所示:
public int Insert(IEnumerable<User> users) { string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username)"); return GetOpenConnection().Execute<User>(sql, users); }
这很整洁,因为我不必写foreach自己。现在,这里的问题是Execute只会返回实际插入的行数。
foreach
Execute
因此,我尝试使用Query以下方法:
Query
public IEnumerable<User> Insert(IEnumerable<User> users) { string sql = string.Format("INSERT INTO [User] (Username) VALUES (@Username) SELECT * FROM [User] WHERE UserId = scope_identity()"); return GetOpenConnection().Query<User>(sql, users); }
但是,这只会引发一条InvalidOperationException异常消息:“在此上下文中不允许使用可枚举的参数序列(数组,列表等)”。
InvalidOperationException
我坚持这一点。我该如何进行这项工作?
我是否必须遍历对循环体内每个对象IEnumerable执行Query的输入?这样,如果我想将所有对象插入同一事务中IDbTransaction,则该方法的参数Query将无用,User因此我必须将整个循环包装在事务中,而不是将事务传递给Query。
IDbTransaction
使用Dapper插入多个对象并将完全填充的对象返回给调用者的“正确”方法是什么?
使用Dapper.Net插入或更新对象列表,不能使用查询
connection.Query<Object>("your_query",your_list) //connection.Query<Object>: use to select IEnumrable<object> from db //connection.QueryMultiple: use to execut multiple query at once then read result one by one var sql = @" select * from Customers where CustomerId = @id select * from Orders where CustomerId = @id select * from Returns where CustomerId = @id"; using (var multi = connection.QueryMultiple(sql, new {id=selectedId})) { var customer = multi.Read<Customer>().Single(); var orders = multi.Read<Order>().ToList(); var returns = multi.Read<Return>().ToList(); ... }
您应该只使用Execute进行多次插入或更新
Execute("your_query",your_list, your_transaction);
因此,如果您需要对插入的记录进行多次插入和返回ID
// **using transaction depend on your needs**
//多次插入并返回完整记录的示例
string query = @"Insert Into _TableName ( _columns) OUTPUT INSERTED.* values ( _parameters )"; //parameters should be same as object properties name to let dapper do correct mapping
[OUTPUT插入。*] 会返回完全插入一行ID,你可以自由返回与PROPERTYNAME星号代替任何属性 [OUTPUT INSERTED.Id] 将返回唯一ID
//对于小清单将是一个好选择
for (int i = 0; i < youList.Count-1; i++) { youList[i] = DbConnection.Query<object>(query, youList[i]).FirstOrDefault(); } // for loop is better for preformance
//对于大列表,您可以使用 SqlBulkCopy在这里查看此链接