5

データ層に .NET 4 と Entity Framework を使用した Windows フォーム アプリケーションがあります。

BLL で:

public int Insert(List<Estrutura> lista)
{
    using (TransactionScope scope = new TransactionScope())
    {
            id = this._dal.Insert(lista);
    }
}

DAL では:

public int Insert(List<Estrutura> lista)
{
   using (Entities ctx = new Entities (ConnectionType.Custom))
   {
     ctx.AddToEstrutura(lista);
     ctx.SaveChanges(); //<---exception is thrown here
   }
}

「基になるプロバイダーが Open で失敗しました。」

誰にもアイデアはありますか?

問題が解決しました - 私の解決策

いくつかの変更を加えて問題を解決しました。私のDALの1つで、一括挿入とその他のエンティティを使用しています。問題のトランザクションは、トランザクション (トランザクション sql) の大部分がトランザクション スコープを理解していないという事実によって発生していました。そのため、DAL でエンティティを分離し、実行中の SQL トランザクションをいくつかの些細なことで使用しました。ExecuteScalar ();

これは最もエレガントな方法ではないと思いますが、トランザクションの問題は解決しました。

これが私のDALのコードです

   using (SqlConnection sourceConnection = new SqlConnection(Utils.ConnectionString()))
   {
        sourceConnection.Open();
        using (SqlTransaction transaction = sourceConnection.BeginTransaction())
        {
            StringBuilder query = new StringBuilder();
            query.Append("INSERT INTO...");
            SqlCommand command = new SqlCommand(query.ToString(), sourceConnection, transaction);
            using (SqlBulkCopy bulk = new SqlBulkCopy(sourceConnection, SqlBulkCopyOptions.KeepNulls, transaction))
            {                           
                bulk.BulkCopyTimeout = int.MaxValue;
                bulk.DestinationTableName = "TABLE_NAME";
                bulk.WriteToServer(myDataTable);

                StringBuilder updateQuery = new StringBuilder();
                //another simple insert or update can be performed here
                updateQuery.Append("UPDATE... ");
                command.CommandText = updateQuery.ToString();
                command.Parameters.Clear();
                command.Parameters.AddWithValue("@SOME_PARAM", DateTime.Now);
                command.ExecuteNonQuery();
                transaction.Commit();
            }
        }
    }

助けてくれてありがとう

4

2 に答える 2

1

全能の Google によると、EF はデータベースへの呼び出しごとに接続を開いたり閉じたりするようです。それを行っているため、トランザクションを複数の接続を使用するものとして扱います (分散トランザクションを使用)。これを回避する方法は、接続を使用するときに手動で接続を開いたり閉じたりすることです。

分散トランザクションの問題に関する情報は次のとおりです。

手動で接続を開いたり閉じたりする方法は次のとおりです。

小さなコード サンプル:

public int Insert(List<Estrutura> lista)
{
    using (TransactionScope scope = new TransactionScope())
    {
        using (Entities ctx = new Entities (ConnectionType.Custom))
        {
            ctx.Connection.Open()

            id = this._dal.Insert(ctx, lista);
        }
    }
}

public int Insert(Entities ctx, List<Estrutura> lista)
{
     ctx.AddToEstrutura(lista);
     ctx.SaveChanges();
}
于 2012-05-22T13:43:18.303 に答える
-1

TransactionScope を採用する代わりに、Entity Framework を操作しながら UnitOfWork パターンを採用することをお勧めします。参照してください: 作業単位パターン

そしてまた;

作業単位と永続性の無視

于 2012-05-22T13:41:37.840 に答える