# ef core

Tags: ef core

# ef core tool 설치

docker 로 .net core app 을 실행 시에 ef core migration 이 필요한 경우가 있음
csproj에 ef core tool 을 포함시킬 경우는

$ dotnet add package Microsoft.EntityFrameworkCore.Design # project 에 직접 포함 (패키지 관리자 콘솔용)
# or
$ dotnet tool install --global dotnet-ef # cli 방식
1
2
3

# ef core migration

migration 생성 및 업데이트

$ dotnet ef migrations add AddColumn --project coreTodoApi.csproj
$ dotnet ef database update --project coreTodoApi.csproj
1
2

scaffolding

$ dotnet ef dbcontext scaffold "Server=localhost;Database=todos;Integrated Security=false;User ID=sa;Password=y0urStrong!Password;" Microsoft.EntityFrameworkCore.SqlServer -o Models
$ dotnet ef dbcontext scaffold "Server=localhost;Database=todos;Integrated Security=false;User ID=sa;Password=y0urStrong!Password;" Microsoft.EntityFrameworkCore.SqlServer -o Models -t TodoItems -t 테이블명 --context-dir Models -c TodoContext --context-namespace Todo.Api
1
2

api 등이 시작되는 시점에서 db migration 하도록 설정하기 위해서는

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
  //   services.AddDbContext<TodoContext>(opt => opt.UseInMemoryDatabase("TodoList"));
  services.AddDbContext<TodoContext>(opt => opt.UseSqlServer("connectionString"));
  services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  // DbContext migrate
  if(app.ApplicationServices.GetService<TodoContext>().Database.GetPendingMigrations().Any())
  {
    app.ApplicationServices.GetService<TodoContext>().Database.Migrate();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# ef core 로 sql server 연결 시 오류

A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)

# 현상

  • .net core 앱을 dockerizing 할 경우, 보통 다음과 같이 Dockerfile 을 작성한다.
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["sample.api.csproj", "./"]
RUN dotnet restore "./sample.api.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "sample.api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "sample.api.csproj" -c Release -o /app/publish

FROM base AS final

LABEL maintainer="Jun Yu <shockzinfinity@gmail.com>"

WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:5001

ENTRYPOINT ["dotnet", "sample.api.dll"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • base 및 build 이미지를 .net standard 5.0 은 mcr.microsoft.com/dotnet/aspnet:5.0, .net core 3.1 은 mcr.microsoft.com/dotnet/aspnet:3.1 등으로 사용하여 dockerizing 하게 되는데,
  • 기본 태그의 이미지는 container 의 size 를 줄이기 위해 buster 나 buster-slim 이다. (dotnet tag (opens new window)) dotnet.docker.tag
  • 해당 태그는 Ubuntu 20.04 등을 사용하여 빌드된 이미지 이다.
  • Ubuntu 20.04 가 되면서 기본 openssl security level 변경되어 다음과 같은 에러가 발생할 수 있다.
System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
1

# 해결





 


...
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:5001
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
ENTRYPOINT ["dotnet", "sample.api.dll"]
1
2
3
4
5
6
  • openssl 의 SECLEVEL 을 조정함으로서 SSL 관련 오류를 우회한다.

# Reference