EG。
public async Task<int> SaveCollectionValues(Foo foo)
{
....
//Parameters
MySqlParameter prmID = new MySqlParameter("pID", MySqlDbType.Int32);
prmID.Value = foo.ID;
sqlCommand.Parameters.Add(prmID);
....
}
(OR)
2。我应该将Collection值传递给Model方法并使用foreach迭代集合
public async Task<int> SaveCollectionValues(FooCollection foo)
{
....
//Parameters
foreach(Foo obj in foo)
{
MySqlParameter prmID = new MySqlParameter("pID", MySqlDbType.Int32);
prmID.Value = foo.ID;
sqlCommand.Parameters.Add(prmID);
....
}
....
}
我只需要知道上面提到的哪种方法可以有效使用?
答案 0 :(得分:1)
由于您没有指定哪个数据库,因此Efficient在这里有点相对。批量插入可能会从一个DB更改为另一个DB。例如,SQL Server使用BCP,而MySQL有一种方法可以在发送许多插入/更新命令时禁用某些内部。
除此之外,如果您一次提交单个集合并且应该作为单个事务处理,而不是代码组织和SQL优化中的最佳选项,则使用连接共享和单个事务对象,如下:
public void DoSomething(FooCollection collection)
{
using(var db = GetMyDatabase())
{
db.Open();
var transaction = db.BeginTransaction();
foreach(var foo in collection)
{
if (!DoSomething(foo, db, transaction))
{ transaction.Rollback(); break; }
}
}
}
public bool DoSomething(Foo foo, IDbConnection db, IDbTransaction transaction)
{
try
{
// create your command (use a helper?)
// set your command connection to db
// execute your command (don't forget to pass the transaction object)
// return true if it's ok (eg: ExecuteNonQuery > 0)
// return false it it's not ok
}
catch
{
return false;
// this might not work 100% fine for you.
// I'm not logging nor re-throwing the exception, I'm just getting rid of it.
// The idea is to return false because it was not ok.
// You can also return the exception through "out" parameters.
}
}
这样你就有了一个干净的代码:一个处理整个集合的方法和一个处理每个值的方法。
此外,虽然您提交的是每个值,但您使用的是单个交易。除了单个提交(更好的性能),如果一个失败,整个集合都会失败,不会留下任何垃圾。
如果你真的不需要所有这些事务,只是不要创建事务并从第二种方法中删除它。保持单一连接,因为这样可以避免资源过度使用和连接开销。
另外,作为一般规则,我想说:“不要一次打开太多连接,特别是当你可以打开一个连接时。永远不要忘记关闭并处理连接,除非你使用连接池并且知道究竟是如何工作的“。