2016-10-13 4 views
0

Я занимаюсь инфраструктурой Entity 4, поскольку приложение уже построено, и мне нужно сделать некоторую градацию в нем.Entity Framework: Atomic Transaction (Database context)

Сценарий: Реализован DBTransaction (вставляет данные в базу данных) в моем коде и один раз транзакция прерывается в середине пути и откат выполняется затем на следующий раз, когда та же самая операция выполняется с правильными/подтвержденных данных до сих пор сделки прервать, предоставив предыдущее исключение. Это довольно сложно понять, поскольку я полагаю, что RollBack должен удалить сообщения проверки и данные из контекста базы данных, так как это SQL. Примечание. Я использую статический DatabaseContext.

public class TestClass 
{ 
    static SampleDataBaseEntities ctx = new SampleDataBaseEntities(); 

    public void SqlTransaction() 
    { 
     ctx.Connection.Open(); 
     using (DbTransaction transaction = ctx.Connection.BeginTransaction()) 
     { 
      try 
      { 
       Student std = new Student(); 
       std.first_name = "first"; 
       //std.last_name = "last"; (This is responsible for generating the exception) 
       AddTeacher(); 
       ctx.AcceptAllChanges(); 
       transaction.Commit(); 
      } 
      catch (Exception e) 
      { 
       transaction.Rollback(); 
      } 
      finally 
      { 
       ctx.Connection.Close(); 
      } 
     } 
    } 

    public void SqlTransaction2() 
    { 
     ctx.Connection.Open(); 
     using (DbTransaction transaction = ctx.Connection.BeginTransaction()) 
     { 
      try 
      { 
       Student std = new Student(); 
       std.first_name = "first"; 
       std.last_name = "last"; 
       AddTeacher(); 
       ctx.Students.AddObject(std); 
       ctx.SaveChanges(false); 
       transaction.Commit(); 
       ctx.AcceptAllChanges(); 
      } 
      catch (Exception e) 
      { 
       transaction.Rollback(); 
       transaction.Dispose(); 
       ctx.Connection.Close(); 
      } 
     } 
    } 

    public void AddTeacher() 
    { 
     Teacher t = new Teacher(); 
     t.first_name = "teacher_first"; 
     t.last_name = "teacher_last"; 
     t.school_name = "PUCIT"; 
     ctx.Teachers.AddObject(t); 
     ctx.SaveChanges(false); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     TestClass test = new TestClass(); 
     test.SqlTransaction(); 
     test.SqlTransaction2(); 
    } 
} 

Solutions (который я пробовал): Используя SaveChanges (ложь). Использование SaveChanges (false) и ctx.AcceptAllChanges().

Обход проблемы: Обходной путь, который я получил, заключается в том, чтобы повторно создать экземпляр объекта DatabaseContext.

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

+0

Не используйте статический объект DatabaseContext. Создайте его так, как вам нужно. Также не требуется ручная обработка транзакции SQL. – Maarten

+0

Каковы проблемы сложности, возникающие при повторном создании контекста? – Maarten

+0

Не используйте статический DbContext, поскольку он не предназначен для обеспечения безопасности потоков. Также всегда используйте инструкцию 'using', чтобы, если что-то пойдет не так, контекст отменит любые изменения. –

ответ

0

«Обходной путь, который я получил, - это повторить объект DatabaseContext».

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

Решение: Старайтесь никогда не использовать статические dataContext, так как вы делаете транзакции очень рано. Таким образом, для каждой транзакции требуется обновленный datacontext. поэтому всегда пытайтесь создать экземпляр нового DataContext и уничтожить его, как только ваша транзакция завершится. Надеюсь, что это сработает!

+0

да! Я решил не создавать статический объект контекста.Любая проблема, связанная с объектами контекста, инициализируется в конструкторе и используется через приложение. В сценарии «Атомная транзакция», когда транзакция прерывается в середине, объекты контекста сохраняют исключение. В следующий раз, когда я попытаюсь использовать этот контекст, он показывает мне предыдущее исключение. Почему это так? –

+0

это потому, что вы снова используете «ошибочный» dataContext. – Umar

+0

Если вам нужен один и тот же объект внутри одного класса, то зачем вам его статичным? Это вызовет проблему, потому что если вы создали несколько объектов TestClass, то будет использоваться тот же грязный dataContext. Поскольку DataContext должен иметь минимальный срок службы. – Umar

2

Все проблемы возникают из-за не создания новых экземпляров контекста. Упростите свой код, и он должен работать.

using (var ctx = new SampleDataBaseEntities()) { 
    Student std = new Student(); 
    std.first_name = "first"; 
    std.last_name = "last"; 
    ctx.Student.Add(std); 
    ctx.SaveChanges(); 
} 
Смежные вопросы