6. entity data model 생성하기 (SQLite)
일반적으로 대부분의 Application은 데이터를 다루는데 관계형 데이터베이스와 같은 DB를 사용합니다. 이와 관련하여 SQL Server나 SQLite에 저장된 데이터베이스를 어떻게 entity data model로 정의할 수 있는지에 대해서 알아보고자 합니다.
우선 이를 위해 SQLite용으로 사용 가능한 Northwind.db를 만들어 두었습니다. 이 파일은 아래 링크에서 내려받으시면 됩니다.
위의 파일을 적당한 위치에 내려받고 나서 이제 해당 db파일을 상대로 dotnet-ef을 통해 entity model을 scaffold 할 것입니다.
(1) SQLite의 entity model을 위한 class library 생성
data model을 위한 class library를 별개로 생성하면 client-side app model을 포함하여 기타 다른 프로젝트에서 쉽게 해당 코드를 재사용할 수 있게 됩니다.
우선 아래 명령을 통해 적당한 위치에서 'Northwind.Common.EntityModels.Sqlite'이름의 새로운 프로젝트를 생성합니다.
dotnet new classlib -n Northwind.Common.EntityModels.Sqlite
|
프로젝트가 생성되면 해당 프로젝트의 프로젝트 파일(csproj)에 아래와 같이 수정하여 SQLite database provider와 EF Core design-time지원을 위한 Nuget 패키지를 추가합니다.
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
해당 프로젝트의 폴더 위치와 동일한 위치에 db폴더를 만들고 위에서 제공한 Northwind.db파일을 저장합니다. 그리고 다시 Northwind.Common.EntityModels.Sqlite프로젝트 폴더 안으로 돌아와 아래 명령을 통해 모든 테이블에 대한 entity class model을 생성합니다.
dotnet ef dbcontext scaffold "Filename=../db/Northwind.db" Microsoft.EntityFrameworkCore.Sqlite --data-annotations |
참고로 위 명령에서 공급자는 Microsoft.EntityFrameworkCore.Sqlite로 하였습니다. 또한 data annotation사용을 위해 --data-annotations옵션을 추가하였습니다.
● class-to-table mapping
dotnet-ef는 SQL Server인가 SQLite인가에 따라 기능적인 차이 때문에 약간의 다른 코드를 생성합니다.
예를 들어 SQL Server의 경우 문자열 칼럼을 지정할때 제한된 문자수를 지정할 수 있지만 SQLite의 경우는 그렇지 않습니다. 때문에 dotnet-ef는 SQL Server에서 string속성에 제한된 문자수를 명시하기 위해 validation attribute를 생성하지만 SQLite는 같은 방법으로 해당 조건을 처리하지 않고 다른 방법을 통해 컬럼을 명시합니다.
//SQLite의 경우
[Column(TypeName = "nvarchar (15)")]
public string CategoryName { get; set; } = null!;
//SQL Server의 경우
[StringLength(15)]
public string CategoryName { get; set; } = null!;
이전 명령을 통해 프로젝트에 생성된 파일 중에는 일부를 수정하여 본래 테이블과의 Mapping정보를 바꿀 수 있습니다. 예를 들어 Customer.cs파일을 아래와 같이 수정하면 CustomerId 멤버에 RegularExpression을 통하여 A부터 Z까지 5개의 문자만 저장이 가능하도록 변경되고 이는 Model차원에서 해당 조건에 맞는 값만 저장될 수 있도록 Validation이 적용되는 효과를 가져올 수 있습니다.
[Key]
[RegularExpression("[A-Z]{5}")]
[Column(TypeName = "nchar (5)")]
public string CustomerId { get; set; } = null!;
● Northwind database context를 위한 class library생성
아래 명령을 통해 Northwind.Common.DataContext.Sqlite이름의 Class Library프로젝트를 생성합니다.
dotnet new classlib -n Northwind.Common.DataContext.Sqlite
|
프로젝트가 생성되면 프로젝트 파일(csproj)을 수정하여 SQLite Nuget 패키지를 추가하고 이전에 만든 Northwind.Common.EntityModels.Sqlite 프로젝트를 참조 추가합니다.
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SQLite" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Northwind.Common.EntityModels.Sqlite\Northwind.Common.EntityModels.Sqlite.csproj" />
</ItemGroup>
그런 다음 Northwind.Common.EntityModels.Sqlite에 있는 NorthwindContext.cs파일을 Northwind.Common.DataContext.Sqlite프로젝트 폴더로 이동합니다.
NorthwindContext.cs파일의 NorthwindContext와 같은 클래스는 필요한 프로젝트에 따라 연결 문자열이 재설정될 수 있습니다. 따라서 DbContext로부터 상속된 클래스는 DbContextOptions 매개변수를 가진 생성자를 가지고 있어야 합니다.
이제 NorthwindContextExtensions.cs 새로운 파일을 추가하고 아래와 같이 Northwind database context를 추가하는 확장 메서드를 정의합니다.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace Northwind.Common.EntityModels.Sqlite;
public static class NorthwindContextExtensions
{
public static IServiceCollection AddNorthwindContext(this IServiceCollection services, string relativePath = @"..\db")
{
string databasePath = Path.Combine(relativePath, "Northwind.db");
services.AddDbContext<NorthwindContext>(options => options.UseSqlite($"Data Source={databasePath}"));
return services;
}
}
프로젝트를 빌드하여 오류가 있는지 확인합니다.
(2) SQL Server를 위한 entity model의 class library 만들기
SQL Server는 연결 정보만 다를 뿐 위에서 했던 절차와 방식이 거의 유사합니다.
아래 명령을 통해 'Northwind.Common.EntityModels.SqlServer'라는 새로운 class library 프로젝트를 생성하고
dotnet new classlib -n Northwind.Common.EntityModels.SqlServer
|
프로젝트 파일(csproj)을 수정하여 필요한 패키지를 추가합니다.
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
그리고 해당 프로젝트에서 아래 명령으로 entity model을 생성합니다.
dotnet ef dbcontext scaffold "Data Source=.;Initial Catalog=Northwind;Integrated Security=true;" Microsoft. EntityFrameworkCore.SqlServer --data-annotations |
공급자는 SqlServer로 하고 Fluent API와 data annotation사용을 위해 --data-annotations옵션을 추가하였습니다.
다시 'Northwind.Common.DataContext.SqlServer'이름의 Class Library형식의 프로젝트를 생성하고
dotnet new classlib -n Northwind.Common.DataContext.SqlServer
|
프로젝트파일(csproj)을 수정해 필요한 패키지와 위에서 생성한 'Northwind.Common.EntityModels.SqlServer'프로젝트를 참조 추가합니다.
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Northwind.Common.EntityModels.SqlServer\Northwind.Common.EntityModels.SqlServer.csproj" />
</ItemGroup>
그리고 'Northwind.Common.EntityModels.SqlServer' 프로젝트 폴더에 있는 'NorthwindContext.cs'파일을 'Northwind.Common.DataContext.SqlServe'프로젝트 폴더로 옮긴 후 'NorthwindContextExtensions.cs'파일을 추가해 아래와 같은 확장 메서드를 정의합니다.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace Northwind.Common.EntityModels.SqlServer;
public static class NorthwindContextExtensions
{
public static IServiceCollection AddNorthwindContext(this IServiceCollection services, string connectionString = "Data Source=.;Initial Catalog=Northwind;Integrated Security=true;MultipleActiveResultsets=true;")
{
services.AddDbContext<NorthwindContext>(options => options.UseSqlServer(connectionString));
return services;
}
}
프로젝트를 빌드하여 오류가 없는지 확인합니다.
'.NET' 카테고리의 다른 글
[C# 12와 .NET 8] 1. .NET 개요 (0) | 2024.01.08 |
---|---|
[.NET] C#과 NET의 프로젝트 유형 - 3. Project 구조설계및 프로젝트 템플릿 (0) | 2022.07.20 |
[.NET] C#과 NET의 프로젝트 유형 - 2. ASP.NET Core와 Windows 전용 Desktop App (0) | 2022.07.20 |
[.NET] C#과 NET의 프로젝트 유형 - 1. App Model (0) | 2022.07.20 |
[.NET] 닷넷 Type 사용하기 - 8. image 다루기 (0) | 2022.06.26 |