문제

나는 두 가지 선택이있는 것 같습니다.

  1. 내 수업을 구현하십시오 IDisposable. 내 DbCommand 인스턴스로 private readonly 필드 및 생성자에 사용하는 매개 변수를 추가하십시오. 데이터베이스에 편지를 쓰고 싶을 때 마다이 매개 변수에 바인딩 (동일한 명령 인스턴스를 재사용) Connection 그리고 Transaction 속성, 전화하십시오 ExecuteNonQuery. 에서 Dispose 방법, 호출 Dispose 이 분야에서.
  2. 데이터베이스에 글을 쓰고 싶을 때마다 쓰기 using(var cmd = new DbCommand("...", connection, transaction)) 명령의 사용과 관련하여 호출하기 전에 매개 변수를 추가하고 매번 바인딩합니다. ExecuteNonQuery. 각 쿼리마다 새 명령이 필요하지 않다고 가정합니다. 데이터베이스를 열 때마다 새 명령 만 (맞습니까?).

이 두 가지 모두 다소 우기적이고 부정확 해 보입니다.

#1의 경우,이 수업이 지금이 수업을하는 것은 내 사용자에게 성가신 일입니다. IDisposable 몇 가지를 사용했기 때문입니다 DbCommandS (신경 쓰지 않는 구현 세부 사항이어야합니다). 나는 또한 a를 유지하는 것이 다소 의심 스럽다 DbCommand 주변 인스턴스가 실수로 데이터베이스를 잠그있을 수 있습니까?

#2의 경우, 데이터베이스에 특히 매개 변수 어드딩을 사용하고 싶을 때마다 많은 작업 (.NET 객체)에서 많은 작업을 수행하는 것처럼 느껴집니다. 매번 같은 객체를 만드는 것 같습니다.

참고로 #1을 사용하여 현재 코드가 있습니다.

using System;
using System.Net;
using System.Data.SQLite;

public class Class1 : IDisposable
{
    private readonly SQLiteCommand updateCookie = new SQLiteCommand("UPDATE moz_cookies SET value = @value, expiry = @expiry, isSecure = @isSecure, isHttpOnly = @isHttpOnly WHERE name = @name AND host = @host AND path = @path");
    public Class1()
    {
        this.updateCookie.Parameters.AddRange(new[]
                            {
                                new SQLiteParameter("@name"),
                                new SQLiteParameter("@value"),
                                new SQLiteParameter("@host"),
                                new SQLiteParameter("@path"),
                                new SQLiteParameter("@expiry"),
                                new SQLiteParameter("@isSecure"),
                                new SQLiteParameter("@isHttpOnly")
                            });
    }

    private static void BindDbCommandToMozillaCookie(DbCommand command, Cookie cookie)
    {
        long expiresSeconds = (long)cookie.Expires.TotalSeconds;

        command.Parameters["@name"].Value = cookie.Name;
        command.Parameters["@value"].Value = cookie.Value;
        command.Parameters["@host"].Value = cookie.Domain;
        command.Parameters["@path"].Value = cookie.Path;
        command.Parameters["@expiry"].Value = expiresSeconds;
        command.Parameters["@isSecure"].Value = cookie.Secure;
        command.Parameters["@isHttpOnly"].Value = cookie.HttpOnly;
    }

    public void WriteCurrentCookiesToMozillaBasedBrowserSqlite(string databaseFilename)
    {
        using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + databaseFilename))
        {
            connection.Open();
            using (SQLiteTransaction transaction = connection.BeginTransaction())
            {
                this.updateCookie.Connection = connection;
                this.updateCookie.Transaction = transaction;

                foreach (Cookie cookie in SomeOtherClass.GetCookieArray())
                {
                    Class1.BindDbCommandToMozillaCookie(this.updateCookie, cookie);
                    this.updateCookie.ExecuteNonQuery();
                }

                transaction.Commit();
            }
        }
    }

    #region IDisposable implementation
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed && disposing)
        {
            this.updateCookie.Dispose();
        }
        this.disposed = true;
    }
    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }
    ~Class1()
    {
        this.Dispose(false);
    }

    private bool disposed;
    #endregion
}
도움이 되었습니까?

해결책

domenic, sqlitecommand를 처분하면 활성 리더가 독자를 처분하도록 신호를 보내고 매개 변수 및 연결 참조를 NULL에 설정합니다.

실행 된 리더를 올바르게 폐기하고 연결을 닫고 폐기하는 한 명령을 캐싱하여 자원이 누출 될 위험이 없습니다.

따라서 캐시 된 명령을 재사용하고 단순히 매개 변수에 값을 할당하는 것이 가장 효율적인 구현입니다.

.prepare ()는 a noop sqlitecommand에서는 그곳에있는 이점이 없습니다.

다른 팁

데이터베이스 객체 수명주기를 처리하는 단일 "올바른 방법"은 없습니다. 그것은 모두 응용 프로그램 요구에 따라 다릅니다.

내 개인적인 취향은 코드를 가능한 한 간단하게 유지하는 것입니다. 필요에 따라 명령 및 매개 변수 개체를 재현하는 경향이 있습니다. 이것은 내 기능을 가능한 한 자체적으로 포함시킬 수있게합니다. 그것은 내가해야 할 모든 팩토링을 크게 단순화했습니다.

재생성 물체의 성능에 관심이 있다면 프로파일 러를로드하고 병 목이 어디에 있는지 확인해야합니다. 내가 구축 한 응용 프로그램에서 DBCommand 객체를 만드는 데 소요되는 시간이 쿼리를 실행하는 데 소요되는 시간과 비교하여 매우 중요하지 않다는 것을 알았습니다.

동일한 연결로 명령을 재사용하면 SQLServer를 발견했습니다. 다른 연결과 거래를 테스트 할 계획이지만 더 빠른 것으로 보입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top