라벨이 Entity Framework인 게시물 표시

XX000: template database "template1" has a collation version mismatch

XX000: template database "template1" has a collation version mismatch Npgsql + EF Core 사용 중 발생한 문제 collation version mismatch 며칠 전부터 Docker 관련 문제로 인해 백업하고 복구하는 과정에서 발생한 문제이다. 아마도 postgres 이미지의 버전업 때문에 발생한 문제로 보인다. 이 문제는 Update-Database (dotnet ef database update) 실행 중 발생했다. 추측하기로 프로젝트에 저장된 마이그레이션 정보에 있는 collcation version과 실제로 마이그레이트 되고 있는 DB의 collation version이 달라서 발생하는 문제 같다. The template database was created using collation version 2.31, but the operating system provides version 2.36. 그렇다면 collation version을 최신화 해주면 된다. Refresh Collation Version PostgreSQL에서 특정 DB의 collation version을 최신화하려면 다음과 같은 쿼리를 날리면 된다. 여기선 문제가 발생한 템플릿 DB인 template1 DB를 대상으로 하겠다. ALTER DATABASE template1 REFRESH COLLATION VERSION ; 잘 적용되었는지 확인해보자. SELECT datcollversion FROM pg_database WHERE datname = 'template1' ; datcollversion 2.36 이제 다시 DB를 업데이트해보면 정상적으로 작동하는 것을 확인할 수 있다.

[C#/EF6] 서로 다른 컨텍스트가 업데이트된 레코드를 읽어야 할 때

여러개의 컨텍스트 사용 필연 우선 이 글은 커넥션 풀링과는 아주 관계가 없진 않으나, 관계가 없다고 생각한 채 읽으셔도 됨을 알려드립니다. 엔티티 프레임워크를 사용해 개발하다 보면 어쩔 수 없이 동일한 컨텍스트 클래스의 인스턴스를 여러 곳에서 생성해 사용하게 됩니다. 처음에 저는 단순한 프로젝트이니 그냥 컨텍스트 클래스를 싱글톤 패턴으로 만들어, 여러 사용처에서 호출해 사용하면 되지 않을까? 라는 어리석은 생각을 했으나, 아무리 단순한 프로젝트라도 그곳에 이벤트가 있고, 병렬 처리가 있다면, 그리고 그 곳에서 DB에 접근해야 한다면(즉, 컨텍스트 인스턴스 호출을 해야 한다면), 어쩔 수 없습니다. 싱글톤은 답이 아닙니다. 문제는 이렇게 할 경우에 여러 동일한 컨텍스트 클래스의 인스턴스에서 동일한 Entity의 정보를 읽고 쓸 수 있다는 것입니다. 예를 들어 동일한 컨텍스트 클래스의 서로 다른 인스턴스를 호출해 사용하는 A, B 클래스가 있다고 가정해봅시다. 아래 가정은 시간 순서로 쓰여졌습니다. B 인스턴스에서 Road 엔티티를 DB에서 컨텍스트로 읽어드렸습니다. (DB => In memory, FindAsync 사용) B 인스턴스에서 Road 엔티티의 (ICollection )Cars.Count 프로퍼티를 읽어 변수 prevCarCount 에 저장했습니다. B 인스턴스에서 유틸리티 클래스인 A 인스턴스의 AddCarOnRoad 를 호출했습니다. A 인스턴스에서 Road 엔티티의 (ICollection )Cars 프로퍼티를 수정했습니다. (새 컨텍스트 인스턴스에서 작업) B 인스턴스에서 Road 엔티티의 (ICollection )Cars.Count 프로퍼티를 읽어 변수 curCarCount 에 저장했습니다. B 인스턴스에서 prevCarCount와 curCarCount가 같으면 throw, 아니면 반환합니다. 위와 같은 상황에서, 어떤 한 로직을 빠뜨리면 3. 에서 Car 를 Road ...

[C#/EntityFrameworkCore] 닷넷 코어에서 Code First 마이그레이션 설정중 OnConfiguring을 오버라이드 할 수 없을 때 해결 방법 (+ SQLite UseSqlite 확장 메서드 사용 방법)

이미지
.Net Core EF 닷넷 코어도 당연히 닷넷 프레임워크와 같이 엔티티 프레임워크를 지원합니다. code-first 마이그레이션 역시 닷넷 프레임워크 EF와 굉장히 비슷합니다. 그러나, 패키지 설치 미스에 따라 곤란한 상황을 겪게 될 수도 있습니다. OnConfiguring 오버라이드 불가 그 문제는 바로 DbContext.OnConfiguring을 오버라이드해 사용해야 하는데, 정작 오버라이드할 DbContext 클래스의 OnConfiguring 메서드가 보이지 않는 문제입니다. OnModelCreating, OnChangeEventHandler등이 보이나, OnConfiguring은 보이지 않는 모습 왜 그럴까요? 사실, 생각해볼 것도 없이, 단순히 지금 여러분이 상속한 DbContext 클래스에 OnConfiguring 메서드가 없기 때문 입니다. 그렇다면 왜 없을까요? 여기서 바로 이 글 처음에 말했던 패키지 설치 미스가 나오게 됩니다. .Net Core EF Code-First를 사용하기 위해 필요한 패키지 닷넷 코어 엔티티 프레임워크를 사용하려면, 당연히 엔티티 프레임워크를 지원하는 DB의 라이브러리가 필요합니다. MySQL, MSSQL, SQLite, … 등등 많은 DB는 현재 엔티티 프레임워크를 지원하는 패키지를 NuGet에 배포하고 있습니다. 하지만, 거기서 끝이 아닙니다. 예를 들어 SQLite를 사용한다고 가정해볼까요? 여러분은 NuGet으로 System.Data.SQLite.Core, System.Data.SQLite.EF6 패키지를 설치할 겁니다. 만약 여기서 끝났다고 생각하고 DbContext를 만들면 위의 이미지와 같은 상황이 생기게 됩니다. 왜냐, System.Data.Entity.DbContext에는 OnConfiguration 메서드가 없기 때문입니다. 여러분이 제대로 된 DbContext를 상속받아 사용하시려면, Microsoft.EntityFrameworkCore 패키지 역시 설치...

[MySQL EF 6] System.NotSupportedException: Unable to create a constant value of type [타입명] 예외 해결 방법

  해당 예외가 발생하는 이유는 여러가지가 있겠으나 이번에 제가 경험한 내용을 바탕으로 글을 쓰도록 하겠습니다. 이 방법으로 해결이 안 되는 분께선 구글신의 힘을 빌리도록 하시길 바랍니다. 잘못된 비교 로직   여기 3개의 기본 키를 포함한 원시 타입과 1개의 외래 키 객체를 지니는 모델이 있습니다. public class ExampleModel { [Key] public int Id { get; set; } public decimal UpperLimitPrice { get; set; } public decimal MaximumPrice { get; set; } public UserModel User { get; set; } }   그리고 우리는 수많은 Example 중에서 특정 User 와 일치하는 레코드를 가져오고자 합니다. 직관적인 예를 들면, 게시판이 있는 웹 서비스에서 '내 글 보기'와 같은 기능을 구현 한다고 생각하시면 편합니다.   이때, 아래와 같이 코딩을 하면 이 포스트의 제목과 같은 예외가 발생하게 됩니다. _context.ExampleList.Where(ex => ex.User == userClient);   왜일까요? 이유는 바로 EF에서 원시 타입이 아닌 객체의 비교를 지원하지 않기 때문 입니다. 즉, string, int, long, float, double, decimal, ... 이런 타입이라면 비교가 가능하지만, 사용자가 직접 만든 클래스의 객체, 여기선 UserModel의 객체에 대한 비교는 지원하지 않는다는 것이죠.   이유를 생각해보면 간단합니다. 우리가 SQL로 SELECT 쿼리를 날릴 때, 예를 들어 게시판에서 특정 유저가 쓴 글의 레코드만 가져온다고 하면 SELECT id, title, body, registeredDate FROM board WHERE userId = '[외래 키로 연결된 유저 테이...