.NET 앱에서 Microsoft.Data.SqlClient 사용

이 퀵스타트에서는 다음과 같은 .NET 콘솔 애플리케이션을 만듭니다:

  • 소스 코드 대신 환경에서 연결 문자열을 읽습니다.
  • 비동기식으로 연결을 엽니다.
  • 테이블이 없으면 생성합니다.
  • 매개변수화된 명령어가 포함된 행을 삽입합니다.
  • 매개변수화된 쿼리가 있는 행을 읽습니다.
  • SQL과 취소 오류를 처리합니다.

이 예제에서는 현재 안정화된 최신 릴리스인 Microsoft.Data.SqlClient 7.0.3을 사용합니다.

사전 요구 사항

.NET 10 SDK나 이후 지원되는 .NET SDK가 필요합니다.

SQL 데이터베이스 만들기

다음 플랫폼 중 하나에서 SQL 데이터베이스를 생성하거나 연결하세요:

퀵스타트는 자체 테이블을 생성하므로 샘플 데이터가 필요하지 않습니다. 데이터베이스 정체성은 연결하고 테이블을 생성, 삽입, 선택하려면 권한이 필요합니다.

Microsoft Fabric의 SQL 데이터베이스 경우, SQL 데이터베이스 항목에서 서버와 데이터베이스 이름을 복사하세요. SQL 분석 엔드포인트는 사용하지 마세요. 아이덴티티에는 항목 읽기 권한이 필요하며, 이 권한은 워크스페이스 역할 또는 항목 권한으로 부여할 수 있습니다. 자세한 내용은 SQL 데이터베이스의 인증(Authentication)을 참조하세요. SQL 인증은 지원되지 않습니다.

Azure SQL Database의 경우, Microsoft Entra ID 인증 및 데이터베이스 접근 설정을 하세요.

프로젝트를 만듭니다.

다음 명령을 실행하세요.

dotnet new console --framework net10.0 --name SqlClientQuickstart
cd SqlClientQuickstart
dotnet add package Microsoft.Data.SqlClient --version 7.0.3
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version 7.0.3

확장 패키지는 드라이버가 제공하는 Microsoft Entra ID 인증 모드를 제공합니다. Windows 통합 인증이나 SQL 인증만 사용하는 애플리케이션은 . 를 생략할 수 있습니다.Microsoft.Data.SqlClient.Extensions.Azure

연결 설정

데이터베이스의 환경 변수를 SQL_CONNECTION_STRING 설정하세요. 소스 코드에 비밀번호, 액세스 토큰 또는 프로덕션 연결 문자열을 넣지 마세요.

이 시작 지점 중 하나를 선택하고 자리 표시자를 교체하세요.

Fabric SQL 또는 비밀번호 없는 인증 기능을 가진 Azure SQL

데이터베이스에 접근할 수 있는 Microsoft Entra ID 신원으로 로그인하세요. 로컬 개발을 위해서는 Azure CLI와 같은 개발자 도구를 사용하세요:

az login

Fabric이나 Azure SQL 데이터베이스의 SQL 데이터베이스 항목에서 정확한 서버와 데이터베이스 이름을 복사하세요. PowerShell의 경우:

$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'

Bash의 경우:

export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'

Azure에서 호스팅된 애플리케이션이 Azure SQL에 연결된다면, 관리 신원 데이터베이스 접근 권한을 부여한 후 Authentication=Active Directory Managed Identity. 다른 Microsoft Entra ID 옵션에 대해서는 Microsoft Entra ID 인증을 참조하세요.

TCP를 통한 SQL Server

기존 SQL Server 또는 따라한 설정 가이드의 서버, 포트, 데이터베이스 및 로그인 정보를 사용하세요. 다음 SQL 인증 예시는 로컬 개발 컨테이너를 위한 것입니다. PowerShell의 경우:

$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;User ID=<user_id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'

Bash의 경우:

export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;User ID=<user_id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'

Caution

TrustServerCertificate=true 서버 인증서 검증을 건너뛸 수 있습니다. 신뢰할 수 있는 인증서가 없는 로컬 개발 인스턴스에서만 사용하세요. 공유 또는 운영 SQL Server 인스턴스의 경우 클라이언트가 신뢰하는 인증서를 설치하고, 해당 인증서에 있는 서버 이름을 사용하며, TrustServerCertificate=true를 제거하세요.

환경이 Windows 통합 인증이나 Kerberos를 지원한다면, 와 PasswordIntegrated Security=true를 로 대체 User ID 하세요. 설정 요구사항에 대해서는 SQL Server 인증을 참조하세요.

애플리케이션 코드 추가

Program.cs의 내용을 다음 코드로 바꿉니다.

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

string? connectionString =
    Environment.GetEnvironmentVariable("SQL_CONNECTION_STRING");

if (string.IsNullOrWhiteSpace(connectionString))
{
    Console.Error.WriteLine(
        "Set the SQL_CONNECTION_STRING environment variable.");
    return 1;
}

using var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
    eventArgs.Cancel = true;
    cancellation.Cancel();
};

try
{
    await using var connection = new SqlConnection(connectionString);
    await connection.OpenAsync(cancellation.Token);

    const string createTableSql = """
        IF OBJECT_ID(N'dbo.SqlClientQuickstart', N'U') IS NULL
        BEGIN
            CREATE TABLE dbo.SqlClientQuickstart
            (
                Id int IDENTITY(1, 1) PRIMARY KEY,
                Message nvarchar(200) NOT NULL,
                CreatedAt datetimeoffset NOT NULL
                    CONSTRAINT DF_SqlClientQuickstart_CreatedAt
                    DEFAULT sysdatetimeoffset()
            );
        END;
        """;

    using (var createCommand =
        new SqlCommand(createTableSql, connection) { CommandTimeout = 30 })
    {
        await createCommand.ExecuteNonQueryAsync(cancellation.Token);
    }

    const string insertSql = """
        INSERT INTO dbo.SqlClientQuickstart (Message)
        OUTPUT INSERTED.Id
        VALUES (@message);
        """;

    int insertedId;
    using (var insertCommand =
        new SqlCommand(insertSql, connection) { CommandTimeout = 30 })
    {
        insertCommand.Parameters.Add(
            new SqlParameter("@message", SqlDbType.NVarChar, 200)
            {
                Value = "Hello from Microsoft.Data.SqlClient"
            });

        object? result =
            await insertCommand.ExecuteScalarAsync(cancellation.Token);
        insertedId = Convert.ToInt32(result);
    }

    const string querySql = """
        SELECT Id, Message, CreatedAt
        FROM dbo.SqlClientQuickstart
        WHERE Id = @id
        ORDER BY Id;
        """;

    using var queryCommand =
        new SqlCommand(querySql, connection) { CommandTimeout = 30 };
    queryCommand.Parameters.Add(
        new SqlParameter("@id", SqlDbType.Int) { Value = insertedId });

    await using SqlDataReader reader =
        await queryCommand.ExecuteReaderAsync(cancellation.Token);

    while (await reader.ReadAsync(cancellation.Token))
    {
        Console.WriteLine(
            $"{reader.GetInt32(0)}: {reader.GetString(1)} " +
            $"at {reader.GetDateTimeOffset(2):O}");
    }

    return 0;
}
catch (OperationCanceledException)
{
    Console.Error.WriteLine("The operation was canceled.");
    return 2;
}
catch (SqlException ex)
{
    Console.Error.WriteLine(
        $"SQL error {ex.Number}, connection {ex.ClientConnectionId}: " +
        ex.Message);
    return 3;
}

매개변수 유형과 크기는 테이블 열과 일치합니다. 매개변수는 SQL 텍스트와 별도로 값을 전송하여, 해당 값들이 명령어 문법을 변경하지 않도록 하고 SQL Server가 쿼리 계획을 재사용할 수 있도록 돕습니다.

await using 예외가 발생하더라도 리더 및 연결을 해제합니다. 연결을 폐기하면 애플리케이션 수명 동안 한 연결을 열어두는 대신 물리적 연결을 연결 풀로 되돌려 보냅니다.

애플리케이션 실행

애플리케이션을 실행합니다.

dotnet run

애플리케이션은 삽입한 행을 출력합니다:

1: Hello from Microsoft.Data.SqlClient at <timestamp>

식별 값과 타임스탬프는 각 데이터베이스마다 다릅니다.

연결이 실패하면 오류 출력에서 SQL 오류 번호와 클라이언트 연결 ID를 사용하세요. 서버 및 데이터베이스 이름, 네트워크 접근, 데이터베이스 권한, 인증 설정, 인증서 설정을 확인하세요. 일반적인 연결 해결책으로 Azure SQL이나 프로덕션 연결에 추가 TrustServerCertificate=true 하지 마세요.

애플리케이션에서 패턴 사용

샘플을 API, 서비스, 데스크톱 애플리케이션, 백그라운드 워커로 옮길 때 다음과 같은 경계를 유지하세요:

  • 애플리케이션 설정 시스템을 통해 연결 정보를 불러옵니다.
  • 짧은 작업 단위를 위해 한 연결을 열고, 그 후 폐기하세요.
  • open, command 및 reader 호출에 CancellationToken를 전달하세요.
  • 명령 타임아웃을 운영에 따라 설정하세요.
  • SQL 문장 외부에서 오는 모든 값에 대해 매개변수를 사용하세요.
  • 자격 증명이나 액세스 토큰은 기록하지 않고 SqlException.NumberClientConnectionId를 기록하세요.
  • 재시도는 일시적인 오류에 대해서만 추가하고, 작업을 반복해도 안전한 경우에만 사용하세요.

다음 단계