2017-12-26 31 views
1

C# 프로그래밍을 연습하기 위해 Microsoft.Data.SQLite을 사용하여이 간단한 SQLite 쿼리 작성기 + ORM을 만들었으며 코드가 작동하는지 확인하기 위해 몇 가지 단위 테스트 (xunit 사용)를 작성했습니다. 문제는 각 단위 테스트를 개별적으로 실행하면 문제가 발생하지만 모든 테스트가 한 번에 모두 실패하면 코드가 실패하고 데이터베이스가 잠겨 있거나 코드가 무한 루프로 진행됩니다.C#의 간단한 SQLite ORM

lock(variable) {}을 사용하여 코드를 threadsafe로 만드는 방법이 있는지 궁금합니다. 확실하지 않습니다. 트랜잭션을 처리하는 방식에 문제가있을 수 있습니다 (INSERT 문에 대해서만 트랜잭션을 사용했습니다).

이것은 문제가되는 기능입니다. 도움이나 의견을 보내 주시면 대단히 감사하겠습니다.

/// <summary> 
/// Helper function that creats SQL commands 
/// </summary> 
/// <param name="commandText"></param> 
/// <returns></returns> 
private void CreateAndExecuteNonQueryCommand(string commandText) 
{ 
    if (SqliteConnection.State != ConnectionState.Open) 
    { 
     SqliteConnection.Open(); 
    } 

    var transaction = SqliteConnection.BeginTransaction(); 
    var command = SqliteConnection.CreateCommand(); 
    command.Transaction = transaction; 

    Transactions.Add(transaction); 

    try 
    {    
     command.CommandText = commandText; 
     command.ExecuteNonQuery(); 
    } 
    catch (Exception e) 
    { 
     throw new ArgumentException(e?.Message); 
    } 
    finally 
    { 
     transaction.Commit(); 
     transaction.Dispose(); 
     command.Dispose(); 
    } 
} 

코드는 내가이 질문을 쓰기로 조금 너무 오래 this the link 마지막에 커밋이다.

+1

어디에서'SqliteConnection'을 닫으시겠습니까? – EdSF

+0

동의합니다. 이것은 실제로 경쟁 조건이 아니지만 각 장치 테스트간에 리소스가 올바르게 정리되지 않을 수도 있습니다. 유닛 테스트는 의도하지 않고 재생하기 힘든 부작용을 일으킬 수 있으므로 일반적으로 병렬로 실행되지 않습니다. –

+0

마지막으로 트랜잭션 커밋을 수행하는 것이 무엇입니까? 예외가 발생했는지 그리고 어쨌든 커밋을 시도하려는 경우 상관하지 않습니까? – Evk

답변

1

SqliteStorage.cs에는 public T RetrieveModel(Dictionary<string, object> keyValueDictionary) 메서드가 포함되어 있습니다. 거기에서 CreateCommand 메서드를 사용하고 ExecuteReader();을 호출하지만이 판독기는 닫히지 않았습니다. RetrieveModel 하단에 reader.Dispose(); 문자열을 추가하십시오. 이 상황을 피하려면 using 블록을 사용할 수 있습니다. 자동으로 Dispose을 호출합니다.

+0

정말 고마워요! –