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 |