2014-06-08 2 views
0

다른 테이블의 값을 기반으로 테이블에 데이터를 쓰는 저장 프로 시저가 있습니다. 따라서 테이블에서 시작/종료 날짜를 읽은 다음 많은 양의 데이터를 작성하고 별도의 테이블에 씁니다.엔터티 프레임 워크, 트랜잭션 및 저장 프로 시저

사용자가 시작/종료 날짜를 선택한 다음 시작/종료 날짜를 테이블에 저장합니다. 그런 다음 EF 내에서 저장 프로 시저를 호출하고 프로 시저가 방금 업데이트 된 테이블을 읽고 다른 테이블을 채 웁니다.

proc가 실패하면 proc이 쓴 데이터와 테이블의 초기 업데이트를 롤백하고 싶습니다.

'SaveChanges'를 호출하면 데이터가 테이블 (EF에서 완료된 초기 업데이트)에만 기록된다고 생각합니다. 그래서 저는 이것을 호출하고, 그 다음 절차를 호출합니다. 프로 시저가 실패했는지 여부를 감지하는 방법이 있습니까? 그렇다면 모든 udpates를 롤백하십시오 (테이블 업데이트 및 proc 한 모든 기능).

현재, 내 코드는 다음과 같습니다,하지만 SaveChanges를에 paremeter가 유효하지 않은 것 (매개 변수를 원하지 않는다), 그리고 'AcceptAllChanges은'잘못되었습니다

using (var scope = new TransactionScope()) 
{ 
    Context.SaveChanges(false); 
    Context.project_scheduled_event_payments(st.id); 
    Context.AcceptAllChanges(); 
} 

답변

1

당신은 트랜잭션 범위를 사용할 수 있습니다. 당신은 System.Transactions.dll에 대한 참조를 추가하고 MSDN에서을 using System.Transactions;

추가해야합니다 :

을 당신은 SaveChanges를() 또는 SaveChanges를을 (사실)는 EF 단순히 가정 호출하면 그 작품은 괜찮 완료하면 그 , 모든 것이 정상이므로 추적 한 변경 사항을 무시하고 새로운 변경 사항이 나타날 때까지 을 기다립니다.

불행히도 트랜잭션에서 문제가 발생하면 EF가 추적 한 변경 사항을 무시했기 때문에 을 복구 할 수 없습니다.

이것은 SaveChanges를 (거짓) 및 AcceptAllChanges는()에서하는 곳.

SaveChanges를 (거짓)입니다 필요한 데이터베이스를 명령을 실행할 수 있지만, 변경에 개최하는 EF를 알려줍니다, 그래서 그들은 경우에 재생할 수 있습니다 이 필요합니다.

이제 더 광범위한 트랜잭션이 실패하면 SaveChanges (false)를 다시 호출하여 EF 특정 비트를 다시 시도 할 수 있습니다. 또는 상태 관리자를 통해 실패한 것을 기록 할 수 있습니다.

광범위한 트랜잭션이 성공하면 AcceptAllChanges()를 수동으로 호출하면 추적중인 변경 내용은 무시됩니다.

using (TransactionScope scope = new TransactionScope()) 
{ 
    //Do something with context1 

    //Save Changes but don't discard yet 
    context1.SaveChanges(false); 

    //run your secondary procedure, if it succeeds then:  
    // 
    // 
    context1.AcceptAllChanges(); 

} 

편집 : .SaveChanges(false)은 (또한 .SaveChanges(SaveOptions)을 위해 사용되지 않는)를 ObjectContext 방법이고 우리가 DbContext이 있기 때문에 좋아, 위에서 작동하지 않습니다.

먼저 우리가 다음 using System.Data.Entity.Infrastructure;을 추가해야합니다 :

using (TransactionScope scope = new TransactionScope()) 
{ 
    // do something with your context 


    // cast your context to IObjectContextAdapter to get access to the full SaveChanges(SaveOptions) method 

    IObjectContextAdapter contextAdapter = context; 

    // .DetectChangesBeforeSave is the equivalent of .SaveChanges(false); 
    contextAdapter.ObjectContext.SaveChanges(
     System.Data.Entity.Core.Objects.SaveOptions.DetectChangesBeforeSave); 

    //run your secondary procedure, if it succeeds then:  
    // 
    // 

    contextAdapter.ObjectContext.AcceptAllChanges(); 

    scope.Complete(); 

} 
+0

감사 톰 우리는 DbContextObjectContext 래퍼 알고, 그래서 우리는 .SaveChanges(SaveOptions) 방법에 대한 액세스 권한을 얻기 위해 IObjectContextAdapter를 사용할 수 있습니다. EF5에서 사용할 수 있습니까? '비 식별 할 수있는'TransactionScope '문제가 발생합니다. – Craig

+0

@Craig 내 대답이 업데이트되었습니다. 참조가 누락되었다고 생각합니다. –

+0

Thanks @Tom -하지만 이제 SaveChanges와 겨루고 있습니다. 부울 매개 변수를 원하지 않습니다. 제로 인수를 원합니다. 어쩌면 모든 문서가 "EF6 특정"이라고 말하는 것 같아서 EF6에 갈 필요가 있을까요? – Craig

관련 문제