Как получить доступ к данным, которые были вставлены с помощью транзакции ADO.NET? - PullRequest
0 голосов
/ 02 июня 2009

Я пытаюсь получить данные, которые были успешно введены в базу данных через транзакцию ADO.NET.

Как только вы вызвали trans.Commit (), кажется, нет способа вернуть данные, которые были зафиксированы, так как все столбцы идентификаторов, которые были созданы во время транзакции, являются «виртуальными», так как это автономно набор данных до фиксации

Большое спасибо

[EDIT]

Ах, проблема в том, что я не могу сделать повторный выбор, поскольку у меня нет ничего уникального для выбора, кроме идентификатора данных, вставленных как часть транзакции.

Я не могу получить последний введенный элемент, так как это многопользовательская система

Пример кода из книги, а не рассматриваемый код, но достаточно хороший, чтобы проиллюстрировать, что мне нужно:

using System.Data;
using System.Data.SqlClient;

namespace DataAdapterTransaction
{
    class Program
    {
        private static string sqlConnectString = "Data Source=(local);" +
            "Integrated security=SSPI;Initial Catalog=AdoDotNet35Cookbook;";

        private static string sqlSelect = "SELECT * FROM DataAdapterTransaction";

        static void Main(string[] args)
        {
            object[,] o1 = {{ "1", "field 1.1", "field 2.1" },
                          { "2", "field 1.2", "field 2.2" }};
            InsertRecords(o1);

            object[,] o2 = {{ "3", "field 1.3", "field 2.3" },
                           { null, "field 1.4", "field 2.4" }};
            InsertRecords(o2);

            // Retrieve and output the contents of the table
            SqlDataAdapter daRead = new SqlDataAdapter(sqlSelect, sqlConnectString);
            DataTable dtRead = new DataTable( );
            daRead.Fill(dtRead);
            Console.WriteLine("---TABLE DataAdapterTransaction---");
            foreach (DataRow row in dtRead.Rows)
                Console.WriteLine("Id = {0}\tField1 = {1}\tField2 = {2}",
                    row["Id"], row["Field1"], row["Field2"]);

            Console.WriteLine("\nPress any key to continue.");
            Console.ReadKey( );
        }

        static void InsertRecords(object[,] o)
        {
            DataTable dt = new DataTable( );
            SqlTransaction tran;

            SqlConnection connection = new SqlConnection(sqlConnectString);

            // Create a DataAdapter
            SqlDataAdapter da = new SqlDataAdapter(sqlSelect, connection);
            // Stop updating when an error is encountered for roll back.
            da.ContinueUpdateOnError = false;
            // Create CommandBuilder and generate updating logic.
            SqlCommandBuilder cb = new SqlCommandBuilder(da);
            // Create and fill a DataTable with schema and data
            da.Fill(dt);
            // Open the connection
            connection.Open( );
            // Begin a new transaction and assign it to the DataAdapter
            tran = connection.BeginTransaction( );
            da.SelectCommand.Transaction = tran;

            // Add two rows that will succeed update
            for (int i = 0; i <= o.GetUpperBound(0); i++)
            {
                dt.Rows.Add(new object[] { o[i, 0], o[i, 1], o[i, 2] });
                Console.WriteLine(
                    "=> Row with [Id = {0}] added to DataTable.", o[i, 0]);
            }

            Console.WriteLine("=> Updating data source using DataAdapter.");
            try
            {
                da.Update(dt);
                tran.Commit( );

                Console.WriteLine("\nTRANSACTION COMMIT.\n");
            }
            catch (Exception ex)
            {
                tran.Rollback( );
                Console.WriteLine("\nTRANSACTION ROLLBACK.\n{0}\n", ex.Message);
            }
            finally
            {
                connection.Close( );
            }
        }
    }
}

Хорошо, так что я хочу сразу после фиксации транзакции, я хочу получить (область видимости) последней вставленной строки.

Мое приложение успешно обновило три адаптера данных в рамках транзакции, однако у меня возникают трудности с просмотром окончательных подтвержденных данных. Я могу сделать выбор таблицы и увидеть ее там, но этого на самом деле недостаточно для производственного кода.

SC

Ответы [ 6 ]

1 голос
/ 02 июня 2009

Возможно, вам просто нужно повторно выбрать данные.

0 голосов
/ 03 июня 2009

В этой статье MSDN описывается, как получить значения идентификаторов при вызове метода обновления DataAdapter.

0 голосов
/ 03 июня 2009

К сожалению, нет, я не могу выбрать заново, используя естественный ключ ... Я застрял с идентификацией ... после 8 часов стука головы я подумывал добавить поле guid, чтобы я мог заставить его работать, но решил, что это против моих принципов сдаться!

SC

0 голосов
/ 03 июня 2009

Я понимаю, что вы используете столбцы идентификаторов, но есть ли в данных естественный ключ, который можно использовать для повторного выбора?

(тогда возникает вопрос «зачем использовать тождества», но это совсем другая тема ...)

0 голосов
/ 03 июня 2009

Правильно, поэтому я должен сделать:

// update datatable
da.Update(dt);
// commit updates
tran.Commit( );
// get the updated datatable
da.Fill(dt);

Я предполагаю, что все столбцы идентификаторов будут обновлены.

Я попробую

SC

0 голосов
/ 03 июня 2009

Books Online говорит, что вам следует снова позвонить в Fill для обновления вашего набора данных:

http://msdn.microsoft.com/en-us/library/33y2221y(VS.71).aspx

Обычно я устанавливаю свои команды вставки и обновления таким образом, чтобы они возвращали действительный DataRow для моей таблицы данных и таким образом контролируют обновление строк в приложении.

...