엔터티 프레임 워크 : 하나의 데이터베이스, 여러 DbContext. 이것은 나쁜 생각입니까? [닫은]


213

지금까지 필자 DbContext는 데이터베이스가 데이터베이스를 나타 내기 때문에 응용 프로그램이 하나의 데이터베이스를 사용하는 경우 하나만 원한다고 생각했습니다 DbContext.

그러나 일부 동료는 기능 영역을 별도의 DbContext클래스 로 나누기를 원합니다 .

나는 이것이 코드를 깨끗하게 유지하려는 욕구에서 좋은 곳에서 온다고 생각하지만 변동성이있는 것 같습니다. 내 직감은 나에게 나쁜 생각이라고 말하지만 불행히도 내 직감은 디자인 결정에 충분한 조건이 아닙니다.

그래서 찾고 있습니다 :

A) 이것이 왜 나쁜 생각인지에 대한 구체적인 예;

B) 이것이 모두 잘 작동 할 것이라고 보증합니다.


답변:


168

단일 데이터베이스에 대해 여러 컨텍스트를 가질 수 있습니다. 예를 들어 데이터베이스에 여러 데이터베이스 스키마가 포함되어 있고 각 스키마를 별도의 자체 포함 영역으로 처리하려는 경우 유용 할 수 있습니다.

문제는 먼저 코드를 사용하여 데이터베이스를 만들 때입니다. 응용 프로그램의 단일 컨텍스트 만 가능합니다. 이를위한 트릭은 일반적으로 데이터베이스 작성에만 사용되는 모든 엔티티를 포함하는 하나의 추가 컨텍스트입니다. 엔터티의 하위 집합 만 포함하는 실제 응용 프로그램 컨텍스트에는 데이터베이스 이니셜 라이저가 null로 설정되어 있어야합니다.

공유 된 엔터티 유형 및 하나의 컨텍스트에서 다른 컨텍스트로의 전달 등과 같이 여러 컨텍스트 유형을 사용할 때 표시되는 다른 문제가 있습니다. 일반적으로 가능하면 디자인을 훨씬 깔끔하게 만들고 다른 기능 영역을 분리 할 수 ​​있지만 추가 복잡성의 비용.


21
애플리케이션에 엔티티 / 테이블이 많은 경우 앱당 단일 컨텍스트를 사용하면 비용이 많이들 수 있습니다. 따라서 스키마에 따라 여러 컨텍스트를 갖는 것이 좋습니다.
DarthVader

7
pluralsight에 가입하지 않았기 때문에이 Q / A 이후에 잘 작성된 Julie Lerman ( 그녀의 의견 ) 의이 멋진 기사를 찾았습니다 . msdn.microsoft.com/en-us/magazine/jj883952.aspx
Dave T.

명명 규칙에 따라 동일한 데이터베이스에서 여러 dbcontext를 지원하는 엔티티 프레임 워크를 제안합니다. 이러한 이유로 나는 모듈 식 응용 프로그램 목적으로 여전히 내 자신의 ORM을 작성하고 있습니다. 단일 응용 프로그램이 단일 데이터베이스를 사용하도록 강요하기는 어렵습니다. 특히 웹 팜에서는 데이터베이스 수가 제한되어 있습니다.
자유 의지

또한 PM Console을 통해 프로젝트 내 한 컨텍스트에 대해서만 Enable-Migrations를 사용할 수 있음을 깨달았습니다.
Piotr Kwiatek

9
@PiotrKwiatek 귀하의 의견과 지금 사이에 이것이 변경되었는지 확실하지 않지만 Enable-Migrations -ContextTypeName MyContext -MigrationsDirectory Migrations\MyContextMigrations지금 작동합니다.
Zack

60

나는 약 4 년 전에이 답변을 썼는데 제 의견은 변하지 않았습니다. 그러나 그 이후로 마이크로 서비스 분야에서 상당한 발전이있었습니다. 마지막에 마이크로 서비스 관련 메모를 추가했습니다 ...

표를 뒷받침 할 실제 경험을 바탕으로 아이디어에 반대합니다.

단일 데이터베이스에 대한 5 개의 컨텍스트가있는 큰 응용 프로그램으로 전환되었습니다. 결국 우리는 하나의 컨텍스트로 돌아가는 것을 제외하고 모든 컨텍스트를 제거했습니다.

처음에는 여러 상황에 대한 아이디어가 좋은 아이디어처럼 보입니다. 데이터 액세스를 도메인으로 분리하고 몇 가지 깔끔하고 가벼운 컨텍스트를 제공 할 수 있습니다. DDD처럼 들리 죠? 이는 데이터 액세스를 단순화합니다. 또 다른 주장은 필요한 컨텍스트에만 액세스한다는 점에서 성능에 대한 것입니다.

그러나 실제로 응용 프로그램이 커짐에 따라 많은 테이블이 다양한 컨텍스트에서 관계를 공유했습니다. 예를 들어, 컨텍스트 1에서 테이블 A에 대한 쿼리는 컨텍스트 2에서 테이블 B를 조인해야했습니다.

이것은 우리에게 몇 가지 잘못된 선택을 남겼습니다. 다양한 상황에서 테이블을 복제 할 수 있습니다. 우리는 이것을 시도했다. 이로 인해 각 엔티티에 고유 한 이름이 있어야하는 EF 제한 조건을 포함한 여러 맵핑 문제점이 발생했습니다. 그래서 우리는 다른 상황에서 Person1과 Person2라는 엔티티로 끝났습니다. 우리는 이것이 저조한 디자인이라고 주장 할 수 있지만 최선의 노력에도 불구하고 이것이 실제로 응용 프로그램이 실제로 성장하는 방식입니다.

또한 필요한 데이터를 얻기 위해 두 컨텍스트를 모두 쿼리했습니다. 예를 들어, 우리의 비즈니스 로직은 컨텍스트 1에서 필요한 것의 절반을 컨텍스트 2에서 요구합니다. 단일 컨텍스트에 대해 하나의 쿼리를 수행하는 대신 서로 다른 컨텍스트에서 여러 쿼리를 수행해야했습니다. 이것은 실제 성능 저하가 있습니다.

결국 좋은 소식은 여러 컨텍스트를 쉽게 제거 할 수 있다는 것입니다. 문맥은 가벼운 물체로 만들어졌습니다. 따라서 여러 상황에서 성능이 좋은 주장이라고 생각하지 않습니다. 거의 모든 경우에있어, 단일 컨텍스트는 더 단순하고 덜 복잡하며 성능이 더 우수 할 것으로 생각하며,이를 위해 많은 해결 방법을 구현할 필요가 없습니다.

여러 상황이 유용 할 수있는 상황을 생각했습니다. 실제로 하나 이상의 도메인을 포함하는 데이터베이스의 물리적 문제를 해결하기 위해 별도의 컨텍스트를 사용할 수 있습니다. 이상적으로 컨텍스트는 도메인과 일대일이며 데이터베이스와 일대일입니다. 즉, 테이블 세트가 주어진 데이터베이스의 다른 테이블과 관련이없는 경우 별도의 데이터베이스로 가져와야합니다. 이것이 항상 실용적이지는 않다는 것을 알고 있습니다. 그러나 테이블 세트가 너무 다르기 때문에 테이블을 별도의 데이터베이스로 분리하는 것이 편하다고 생각하지만 (그렇지 않은 경우) 실제로는 별도의 도메인이 두 개 있기 때문에 별도의 컨텍스트를 사용하는 경우를 볼 수 있습니다.

마이크로 서비스와 관련하여 하나의 단일 컨텍스트가 여전히 의미가 있습니다. 그러나 마이크로 서비스의 경우 각 서비스에는 해당 서비스와 관련된 데이터베이스 테이블 만 포함하는 고유 한 컨텍스트가 있습니다. 다시 말해, 서비스 x가 테이블 1 및 2에 액세스하고 서비스 y가 테이블 3 및 4에 액세스하는 경우, 각 서비스는 해당 서비스에 특정한 테이블을 포함하는 고유 한 컨텍스트를 갖습니다.

나는 당신의 생각에 관심이 있습니다.


8
특히 기존 데이터베이스를 대상으로 할 때 여기에 동의해야합니다. 나는 지금이 문제에 대해 연구하고 있으며 지금까지 내 직감은 다음과 같다. 1. 여러 상황에서 동일한 물리적 테이블을 갖는 것은 나쁜 생각이다. 2. 테이블이 어떤 컨텍스트에 속하는지 결정할 수 없다면, 두 컨텍스트는 논리적으로 분리 될만큼 충분히 명확하지 않습니다.
jkerak

3
CQRS를 수행 할 때 컨텍스트간에 관계가 없으므로 (각보기마다 고유 한 컨텍스트를 가질 수 있음)이 경고는 여러 컨텍스트를 원할 경우 모든 경우에 적용되지 않습니다. 결합하고 참조하는 대신 각 컨텍스트에 데이터 복제를 사용하십시오. -이 :하지만이 답변의 유용성을 부정하지 않습니다
urbanhusky

1
나는 당신이 깊이 직면 한 고통을 느꼈습니다! : / 또한 단순성을 위해 하나의 컨텍스트가 더 나은 선택이라고 생각합니다.
ahmet

1
내가 완전히 동의한다는 것에 반대하는 나의 유일한 주장은 정체성에 관한 것이다. 특히 수평 확장의 경우로드 밸런싱이 도입되는 거의 모든 경우에 ID 계층이 분리되어야합니다. 적어도 내가 찾은 것입니다.
Barry

5
나에게 당신의 집계가 다른 집계를 알아야 할 필요가 있다면 DDD를 끝까지 가지 않은 것처럼 보입니다. 무언가를 참조 해야하는 이유는 두 가지 이유가 있습니다. 동일한 집계에 있음은 동일한 거래에서 변경되어야하거나 그렇지 않다는 것을 의미합니다.
Simons0n

54

이 스레드는 방금 StackOverflow에서 버블 링되었으므로 다른 "B) 이것이 모두 괜찮을 것이라는 확신을 제공하고 싶었습니다. :)

DDD Bounded Context 패턴을 사용하여 정확하게이 작업을 수행하고 있습니다. 필자는이 책에 대해 Programming Entity Framework : DbContext에 썼으며 Pluralsight-> http://pluralsight.com/training/Courses/TableOfContents/efarchitecture 과정 중 하나에서 50 분 모듈에 중점을 둡니다 .


7
pluralsight 교육 비디오는 큰 개념을 설명하는 데 매우 좋았지 만, 제공하는 예제는 엔터프라이즈 솔루션 (DbContext 정의가있는 어셈블리의 NuGet이 있거나 모듈 식 어셈블리가 동적으로로드되는 경우)과 비교하여 너무 사소한 것입니다. DDD 경계 컨텍스트는 각 DbSet에 중복 선언을 보유하도록 중복 DbContext가 정의 된 최종 예제에서 완전히 손상되었습니다. 나는 당신이 기술에 의해 제한되어 있음을 이해합니다. 나는 당신의 비디오를 정말로 좋아하지만, 이것으로 더 많은 것을 원했습니다.
Victor Romeo

5
나는 큰 그림을 목표로 방어했다. Big 앱의 문제 해결 패키지는 ef 비디오와 관련이 없습니다. "파손 된"예를 다시 ... 허? 내 강의에 대한 비판이이 포럼의 범위를 벗어 났기 때문에 (아마도 부적절하기 때문에) 개인 콘보에 가져가는 것이 좋습니다. 나는 당신이 저에게 직접 연락 할 수 있다고 생각합니다.
Julie Lerman

57
Julie가 OP의 문제 / 질문에 대한 정보를 공유하게하는 것이 좋았을 것입니다. 그 대신에 게시물은 복수 보험에 대한 유료 가입을 장려하는 것입니다. 제품 플러그라면 제안 된 솔루션 정보에 대한 링크 (DDD 경계 컨텍스트 패턴)가 도움이 될 것입니다. "DDD"는 "Programming Entity Framework : DBContext"의 p.222에 설명되어 있습니까? 'DDD'또는 'Bounded Context'에 대해 (인덱스 없음) 찾아서 찾을 수 없기 때문에 찾을 수 없습니다 ... EF6에 대한 새로운 개정을 기다릴 수 없습니다 ...
자비로운 자기애 주의자

12
죄송합니다. 홍보를 원치 않고 OP "보증을 원합니다"에 추가했습니다. Ladislav와 다른 사람들은 세부 사항을 잘 다루었습니다. 그래서 나는 이미 내가 만든 무언가를 시도하고 있었을 것입니다. 다음은 자료의 일부를 자세히 다룬 다른 리소스입니다. msdn.microsoft.com/en-us/magazine/jj883952.aspx & msdn.microsoft.com/en-us/magazine/dn342868.aspx & oredev.org / 2013 / wed-fri-conference /…
Julie Lerman

@JulieLerman의 코드 제안 요약 내 답변을 참조하십시오 stackoverflow.com/a/36789520/1586498
OzBob

46

기본 스키마를 설정하여 컨텍스트 구별

EF6에서는 여러 컨텍스트를 가질 수 있으며 파생 클래스 의 OnModelCreating메소드 DbContext(Fluent-API 구성이있는 위치) 에서 기본 데이터베이스 스키마의 이름을 지정하기 만하면 됩니다. 이것은 EF6에서 작동합니다 :

public partial class CustomerModel : DbContext
{   
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("Customer");

        // Fluent API configuration
    }   
}

이 예에서는 "dbo"대신 "Customer"를 데이터베이스 테이블의 접두어로 사용합니다. 더 중요한 것은 __MigrationHistory테이블 앞에 접두사를 추가하는 것입니다 (예 :) Customer.__MigrationHistory. 따라서 __MigrationHistory단일 데이터베이스에 각 컨텍스트마다 하나씩 둘 이상의 테이블 이있을 수 있습니다 . 따라서 한 컨텍스트에서 변경 한 내용은 다른 컨텍스트와 혼동되지 않습니다.

마이그레이션을 추가 할 때 명령 DbMigrationsConfiguration에서 매개 변수로 구성 클래스의 완전한 이름 (에서 파생 됨 )을 지정하십시오 add-migration.

add-migration NAME_OF_MIGRATION -ConfigurationTypeName FULLY_QUALIFIED_NAME_OF_CONFIGURATION_CLASS


컨텍스트 키에 대한 짧은 단어

이 MSDN 기사 " 장-동일한 데이터베이스를 대상으로하는 여러 모델 "에 따르면 EF 6은 MigrationHistory테이블에 ContextKey 가 있기 때문에 하나의 테이블 만 존재 하더라도 상황을 처리 할 수 ​​있습니다. 마이그레이션을 구분하기 열 .

그러나 MigrationHistory위에서 설명한 것처럼 기본 스키마를 지정하여 둘 이상의 테이블을 갖는 것을 선호합니다 .


별도의 마이그레이션 폴더 사용

이러한 시나리오에서는 프로젝트의 다른 "마이그레이션"폴더로 작업 할 수도 있습니다. 속성을 DbMigrationsConfiguration사용 하여 파생 클래스를 설정할 수 있습니다 MigrationsDirectory.

internal sealed class ConfigurationA : DbMigrationsConfiguration<ModelA>
{
    public ConfigurationA()
    {
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"Migrations\ModelA";
    }
}

internal sealed class ConfigurationB : DbMigrationsConfiguration<ModelB>
{
    public ConfigurationB()
    {
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"Migrations\ModelB";
    }
}


요약

결과적으로 컨텍스트, 프로젝트의 마이그레이션 폴더 및 데이터베이스의 테이블 등 모든 것이 완전히 분리되어 있다고 말할 수 있습니다.

더 큰 주제에 속하지만 외래 키를 통해 서로 관련이없는 엔터티 그룹이있는 경우 그러한 솔루션을 선택합니다.

엔터티 그룹이 서로 할 일이없는 경우 각 엔터티에 대해 별도의 데이터베이스를 만들고 각 프로젝트의 단일 컨텍스트를 사용하여 다른 프로젝트에서 액세스 할 수도 있습니다.


다른 상황에있는 2 개의 엔티티를 업데이트해야 할 때 어떻게합니까?
sotn

나는 두 가지 맥락을 모두 알고 있고, 좋은 이름과이 클래스의 책임을 생각하고, 메소드 중 하나에서이 업데이트를 수행하는 새로운 (서비스) 클래스를 만들 것입니다.
Martin

7

아래를 달성하는 간단한 예 :

    ApplicationDbContext forumDB = new ApplicationDbContext();
    MonitorDbContext monitor = new MonitorDbContext();

기본 컨텍스트에서 속성의 범위를 지정하십시오 (DB를 만들고 유지 관리하는 데 사용). 참고 : protected 사용 : (여기서는 엔터티가 노출되지 않습니다)

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("QAForum", throwIfV1Schema: false)
    {

    }
    protected DbSet<Diagnostic> Diagnostics { get; set; }
    public DbSet<Forum> Forums { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Thread> Threads { get; set; }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

MonitorContext : 별도의 엔티티를 여기에 노출

public class MonitorDbContext: DbContext
{
    public MonitorDbContext()
        : base("QAForum")
    {

    }
    public DbSet<Diagnostic> Diagnostics { get; set; }
    // add more here
}

진단 모델 :

public class Diagnostic
{
    [Key]
    public Guid DiagnosticID { get; set; }
    public string ApplicationName { get; set; }
    public DateTime DiagnosticTime { get; set; }
    public string Data { get; set; }
}

기본 ApplicationDbContext 내에서 모든 엔티티를 보호 된 것으로 표시하려면 스키마를 분리 할 때마다 필요에 따라 추가 컨텍스트를 작성하십시오.

모두 동일한 연결 문자열을 사용하지만 별도의 연결을 사용하므로 트랜잭션을 교차시키지 않고 잠금 문제를 인식하지 마십시오. 일반적으로 디자인 분리가 일어나지 않아야합니다.


2
이것은 많은 도움이되었습니다. "보조"컨텍스트는 공유 테이블을 선언 할 필요가 없습니다. 정의를 수동으로 추가하십시오 DbSet<x>. 나는 EF Designer가 만드는 것과 일치하는 부분 클래스에서 그렇게합니다.
Glen Little

당신은 나에게 많은 두통을 저장했습니다. 수락 된 답변 대신 구체적인 솔루션을 제공했습니다. 정말 감사합니다!
WoIIe

6

알림 : 여러 컨텍스트를 결합하는 경우 다양한 기능을 모두 하나의 붙여 넣기로 잘라야 RealContexts.OnModelCreating()합니다 CombinedContext.OnModelCreating().

캐스케이드 삭제 관계가 유지되지 않는 이유를 찾기 위해 시간을 낭비했습니다. modelBuilder.Entity<T>()....WillCascadeOnDelete();실제 컨텍스트 의 코드를 결합 된 컨텍스트로 이식하지 않았다는 것을 발견했습니다 .


6
잘라 내기 및 붙여 넣기 대신 OtherContext.OnModelCreating()결합 된 컨텍스트에서 전화 할 수 있습니까?
AlexFoxGill

4

이 디자인을 만났을 때 내 직감도 같은 말을했다.

하나의 데이터베이스에 세 개의 dbContext가있는 코드베이스에서 작업하고 있습니다. 3 개의 dbcontext 중 2 개는 관리 데이터를 제공하므로 1 개의 dbcontext의 정보에 의존합니다. 이 디자인은 데이터를 쿼리하는 방법에 제약을 두었습니다. 나는 당신이 dbcontexts에 가입 할 수없는이 문제에 부딪쳤다. 대신 두 개의 별도 dbcontext를 쿼리 한 다음 메모리에서 조인을 수행하거나 둘을 반복하여 결과 집합으로이 둘의 조합을 가져옵니다. 문제는 특정 결과 집합을 쿼리하는 대신 모든 레코드를 메모리에로드 한 다음 메모리의 두 결과 집합에 대해 조인을 수행하는 것입니다. 실제로 속도가 느려질 수 있습니다.

나는 "당신이 할 수 있다고 해서요? "

이 디자인과 관련된 문제에 대해서는이 기사를 참조하십시오. 지정된 LINQ 표현식에는 다른 컨텍스트와 연관된 쿼리에 대한 참조가 포함되어 있습니다.


3
나는 우리가 여러 상황을 가진 큰 시스템에서 일했다. 내가 찾은 것 중 하나는 때로는 여러 컨텍스트에 동일한 DbSet을 포함해야한다는 것입니다. 한편으로 이것은 순도 문제를 해결하지만 쿼리를 완료 할 수 있습니다. 읽어야 할 특정 관리 테이블이있는 경우 기본 DbContext 클래스에 추가하고 앱 모듈 컨텍스트에서 상속 할 수 있습니다. "실제"관리자 컨텍스트의 목적은 모든 액세스 권한을 제공하지 않고 "관리 테이블에 대한 유지 보수 제공"으로 재정의 될 수 있습니다.
JMarsch

1
그만한 가치가 있기 때문에 나는 그만한 가치가 있는지 항상 돌아갔다. 한편으로, 별도의 맥락에서 한 모듈에서 작업하고 싶은 개발자에게는 알 필요가 없으며 사용자 정의 프로젝션을 정의하고 사용하는 것이 안전하다고 느끼기 때문에 (다른 모듈에 미치는 영향에 대해 걱정하지 않기 때문에) 모듈). 다른 한편으로, 컨텍스트 간 데이터를 공유해야 할 때 몇 가지 문제가 발생합니다.
JMarsch 2016 년

1
둘 다에 엔터티를 포함시키지 않아도 항상 ID를 얻고 다른 컨텍스트에 대한 두 번째 쿼리를 수행 할 수 있습니다. 작은 시스템의 경우 이것은 나쁘다. 다중 테이블 구조의 많은 개발자 일관성을 가진 큰 DB / 시스템의 경우 2 개의 쿼리보다 훨씬 크고 어려운 문제이다.
user1496062 2016 년

4

[@JulieLerman의 DDD MSDN Mag Article 2013]에서 영감을 받음 [1]

    public class ShippingContext : BaseContext<ShippingContext>
{
  public DbSet<Shipment> Shipments { get; set; }
  public DbSet<Shipper> Shippers { get; set; }
  public DbSet<OrderShippingDetail> Order { get; set; } //Orders table
  public DbSet<ItemToBeShipped> ItemsToBeShipped { get; set; }
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Ignore<LineItem>();
    modelBuilder.Ignore<Order>();
    modelBuilder.Configurations.Add(new ShippingAddressMap());
  }
}

public class BaseContext<TContext>
  DbContext where TContext : DbContext
{
  static BaseContext()
  {
    Database.SetInitializer<TContext>(null);
  }
  protected BaseContext() : base("DPSalesDatabase")
  {}
}   

"새로운 개발을하고 있고 Code First가 클래스를 기반으로 데이터베이스를 만들거나 마이그레이션하도록하려면 DbContext를 사용하여"클래스 모델 "을 만들어야합니다. 여기에는 필요한 모든 클래스와 관계가 포함됩니다. "데이터베이스를 나타내는 완전한 모델을 빌드하십시오. 그러나이 컨텍스트는 BaseContext에서 상속되지 않아야합니다." JL


2

먼저 코드에서 여러 DBContext와 하나의 데이터베이스 만 가질 수 있습니다. 생성자에서 연결 문자열을 지정하기 만하면됩니다.

public class MovieDBContext : DbContext
{
    public MovieDBContext()
        : base("DefaultConnection")
    {

    }
    public DbSet<Movie> Movies { get; set; }
}

예, 가능하지만 다른 DB 컨텍스트의 다른 엔터티에서 어떻게 쿼리 할 수 ​​있습니까?
Reza

2

"지혜"의 또 다른 비트. 인터넷과 내부 앱을 모두 갖춘 데이터베이스가 있습니다. 나는 각 얼굴에 대한 맥락을 가지고 있습니다. 이를 통해 훈련되고 안전한 분리를 유지할 수 있습니다.


1

같은 데이터베이스에 여러 DBContext가있을 가능성이 있다고 생각되는 사례를 공유하고 싶습니다.

두 개의 데이터베이스가있는 솔루션이 있습니다. 하나는 사용자 정보를 제외한 도메인 데이터를위한 것입니다. 다른 하나는 사용자 정보만을위한 것입니다. 이 부서는 주로 EU 일반 데이터 보호 규정 에 의해 운영됩니다 . 두 개의 데이터베이스가 있으면 사용자 데이터가 안전한 장소에 머무르는 한 도메인 데이터를 자유롭게 이동할 수 있습니다 (예 : Azure에서 내 개발 환경으로).

이제 사용자 데이터베이스의 경우 EF를 통해 두 개의 스키마를 구현했습니다. 하나는 AspNet Identity 프레임 워크에서 제공하는 기본입니다. 다른 하나는 우리 자신의 다른 사용자 관련 구현입니다. 나중에 AspNet Identity의 변경 사항을 쉽게 처리 할 수 ​​있고 동시에 프로그래머에게 명확하게 구분할 수 있기 때문에 ApsNet 스키마를 확장하는 것보다이 솔루션을 선호합니다. .


2
답장에 질문이 표시되지 않습니다. 나는 하나의 질문을 요구하지 않습니다! 토론의 주제가 적절한 시나리오를 공유하십시오.
freilebt

0

허, 각 DB 스키마마다 별도의 DB 컨텍스트 관련 문제에 많은 시간을 보냈습니다. 다른 사람에게 도움이되기를 바랍니다.

나는 최근에 3 개의 스키마를 가진 하나의 데이터베이스 (DB first approach)를 가진 프로젝트에서 작업하기 시작했으며 그 중 하나는 사용자 관리 용입니다. 각각의 개별 스키마에서 DB 컨텍스트 스캐 폴딩이있었습니다. 물론 사용자는 다른 스키마와도 관련이있었습니다. schema KB에는 "To create by", "last modified by"등의 테이블 Topic이 있습니다. FK to identity schema, 테이블 appuser.

이 객체는 C #에 별도로로드되었습니다. 먼저 주제가 1 컨텍스트에서로드 된 다음 사용자가 다른 db 컨텍스트에서 사용자 ID를 통해로드되었습니다. ( EF 6과 동일한 데이터베이스에서 여러 dbcontext사용하는 것과 유사 함 )

먼저, ID 스키마에서 KB 스키마, KB DB 컨텍스트의 EF modelBuilder에 누락 된 FK 명령어를 추가하려고했습니다. 하나의 컨텍스트 만있는 것과 동일하지만 2로 분리했습니다.

modelBuilder.Entity<Topic>(entity =>
{
  entity.HasOne(d => d.Creator)
    .WithMany(p => p.TopicCreator)
    .HasForeignKey(d => d.CreatorId)
    .HasConstraintName("fk_topic_app_users");

kb db 컨텍스트에 사용자 객체에 대한 정보가 없으므로 postgres가 error를 반환했기 때문에 작동하지 않았습니다 relation "AppUsers" does not exist. Select 문에 스키마, 필드 이름 등에 대한 적절한 정보가 없습니다.

나는 거의 포기했지만 실행시 스위치 "-d"를 발견했습니다 dotnet ef dbcontext scaffold. -data-annotations의 약자-속성을 사용하여 모델을 구성하십시오 (가능한 경우). 생략하면 유창한 API 만 사용됩니다. 이 스위치를 지정하면 객체 속성이 db context OnModelCreating()가 아니라 속성을 사용하여 객체 자체에 정의되었습니다 .

이런 식으로 EF는 적절한 필드 이름과 스키마를 사용하여 적절한 SQL 문을 생성하기위한 충분한 정보를 얻었습니다.

TL; DR : 별도의 DB 컨텍스트는 그들 사이의 관계 (FK)를 잘 처리하지 못하며, 각 컨텍스트에는 자체 엔티티에 대한 정보 만 있습니다. "-data-annotations"switch on을 지정할 때 dotnet ef dbcontext scaffold이러한 정보는 각각의 별도 컨텍스트에 저장되지 않고 DB 객체 자체에 저장됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.