我需要向数据库添加一个集合值。这是有效的方法吗?

时间:2015-02-18 20:11:15

标签: asp.net-mvc database collections asp.net-mvc-5

  1. 我是否需要将类对象传递给Model方法并一次处理一个?
  2. 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);
    
       ....
       }
       ....
    }
    

    我只需要知道上面提到的哪种方法可以有效使用?

1 个答案:

答案 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.
    }
}

这样你就有了一个干净的代码:一个处理整个集合的方法和一个处理每个值的方法。

此外,虽然您提交的是每个值,但您使用的是单个交易。除了单个提交(更好的性能),如果一个失败,整个集合都会失败,不会留下任何垃圾。

如果你真的不需要所有这些事务,只是不要创建事务并从第二种方法中删除它。保持单一连接,因为这样可以避免资源过度使用和连接开销。

另外,作为一般规则,我想说:“不要一次打开太多连接,特别是当你可以打开一个连接时。永远不要忘记关闭并处理连接,除非你使用连接池并且知道究竟是如何工作的“。