대규모 시스템의 Entity Framework-모델을 나누는 방법?


50

1000 + 테이블, 또 다른 수백 개의 뷰 및 수천 개의 저장 프로 시저가있는 SQL Server 데이터베이스로 작업하고 있습니다. 우리는 새로운 프로젝트에 Entity Framework를 사용하기 시작하고 있으며이를위한 전략을 연구하고 있습니다. 내가 끊은 것은 테이블을 다른 모델로 나누는 가장 좋은 방법입니다 (먼저 코드를 작성하면 EDMX 또는 DbContext). 나는 바로 몇 가지 전략을 생각할 수 있습니다.

  • 스키마로 분할
    우리는 아마도 12 개의 스키마로 테이블을 분할했습니다. 스키 마당 하나의 모델을 수행 할 수 있습니다. 그러나 dbo는 여전히 500 + 테이블 / 뷰로 인해 매우 커지기 때문에 완벽하지 않습니다. 또 다른 문제는 특정 작업 단위가 여러 모델에 걸쳐 트랜잭션을 수행해야하기 때문에 복잡해 지지만 EF가이를 매우 간단하게한다고 가정합니다.
  • 의도별로
    분할 스키마를 걱정하지 않고 모델을 의도별로 분할합니다. 따라서 우리는 세부적인 방법에 따라 각 응용 프로그램, 프로젝트 또는 모듈 또는 화면에 대해 서로 다른 모델을 갖게됩니다. 내가 볼 때 문제는 User 또는 AuditHistory와 같은 모든 경우에 필연적으로 사용해야하는 특정 테이블이 있다는 것입니다. 우리는 그것들을 모든 모델에 추가합니까 (제 생각에 DRY 위반) 또는 모든 프로젝트에서 사용되는 별도의 모델에 있습니까?
  • 전혀 분리하지 마십시오-하나의 거대한 모델
    이것은 개발 관점에서 분명히 간단하지만 제 연구와 직관에 따르면 디자인 타임, 컴파일 타임 및 런타임에 끔찍하게 수행 할 수있는 것처럼 보입니다.

이러한 큰 데이터베이스에 대해 EF를 사용하는 가장 좋은 방법은 무엇입니까? 특히 사람들이이 DB 객체 볼륨에 대한 모델을 설계 할 때 어떤 전략을 사용합니까? 내가 생각하지 않은 옵션이 위에있는 것보다 낫습니까?

또한 이것은 NHibernate와 같은 다른 ORM에서 문제입니까? 그렇다면 EF보다 더 나은 솔루션을 찾게 되었습니까?


"여러 모델에 걸쳐 트랜잭션을 수행하면 복잡성이 증가합니다."여기서 Microsoft Distributed Transaction Coordinator를 활성화해야합니다. 일단 당신이 그것을 실행하면 당신이 말하는 것을 달성하는 것이 간단해야합니다.
Tjaart

@Tjaart 감사합니다. 나는 MS DTC를 사용하기 전과 꽤 단순하지만 간단한 DB TXN을 넘어 복잡성을 추가하므로 가능할 때마다 피하고 싶습니다.
RationalGeek

2
4 년 후, 무엇을 결정했으며 지금 무엇을 추천 하시겠습니까?
Rory

답변:


31

개인적으로, 나는 상당히 복잡하지만 작은 프로젝트 (~ 300 테이블)에서 모든 엔티티에 대해 하나의 거대한 스키마를 만들려고했습니다. 우리는 많은 "다 대다"관계와 극도의 참조 무결성 시행으로 극도로 표준화 된 데이터베이스 (제 5 형식 정규화 (느슨하게 말))를 가졌습니다.

또한 "요청 당 단일 인스턴스"전략을 사용하여 도움이되지 않았습니다.

단순하고 합리적으로 단순한 "명시 적으로 정의 된"리스팅을 수행 할 때 일반적으로 조회 및 성능 절약이 허용됩니다. 그러나 우리가 깊은 관계를 파고 들기 시작했을 때 성능이 급격히 떨어졌습니다. 이 경우 저장된 proc과 비교할 때 (물론) 비교는 없었습니다. 여기에서 코드베이스를 조정하여 성능을 향상시킬 수 있다고 확신하지만이 경우 시간 제약으로 인해 분석하지 않고 성능 향상이 필요했고 저장된 proc로 넘어갔습니다 (아직 매핑 됨) EF를 통해 EF가 강력하게 형식화 된 결과를 제공했기 때문에)는 일부 지역에서 폴백 할 때만 필요했습니다. .include ()를 사용하여 컬렉션을 만들기 위해 데이터베이스 전체를 탐색해야 할 때 성능이 눈에 띄게 저하되었지만 너무 많이 요청했을 수 있습니다.

따라서 내 경험에 따라 의도별로 별도의 .edmx를 만드는 것이 좋습니다. 필요한 범위에 따라 사용할 것을 생성하십시오. 목적에 맞는 작업을 위해 더 작은 범위의 .edmx 파일이있을 수 있으며 복잡한 관계를 탐색하여 개체를 작성해야하는 큰 파일이있을 수 있습니다. 나는 그 마법의 자리가 어디에 있는지 확실하지 않지만, 하나는 ... L ...

솔직히 말해서, 우리가 (복잡한 순회) 다가오는 몇 가지 함정을 제외하고, 거대한 .edmx는 "작업"관점에서 잘 작동했습니다. 그러나 명시 적으로 비활성화하지 않으면 컨텍스트가 장면 뒤에서 수행하는 "수정"마법을 조심해야합니다. 데이터베이스를 변경할 때 .edmx를 동기화 상태로 유지하는 것뿐만 아니라 전체 표면을 지우고 엔터티를 다시 만드는 것이 더 쉬웠습니다. 3 분 정도 걸리므로 큰 문제가되지 않았습니다.

이것은 모두 EntityFramework 4.1과 관련이 있습니다. 나는 당신의 최종 선택과 경험에 대해 정말로 듣고 싶습니다.

그리고 당신이 nHibernate에 관한 질문에 관해서는, 그것은 내 의견으로는 벌레의 깡통 질문입니다, 당신은 울타리의 양쪽에서 짖는 소리를 낼 것입니다 ... EF 자체 고유의 뉘앙스에 대한 도전과 이해 .. 프로덕션에서 nHibernate를 사용한 적이 없지만 일반적으로 매핑과 같은 것을 수동으로 명시 적으로 작성 해야하는 경우 더 엄격한 제어를 얻을 수 있습니다. LINQ를 사용하여 n 'drop을 생성하고 CRUD를 생성하고 쿼리를 시작할 수 있습니다.

이게 도움이 되길 바란다.


1
참고-이러한 매핑을 매우 쉽고 자동화 할 수있는 NHibernate 매핑 유틸리티가 있습니다.
ganders

@ganders-UI가 있고 IDE 통합은 어떻습니까? 데이터 소스를 가리키고 참조 무결성과 객체 순회를 존중하고 매핑 객체를 생성한다고 가정합니다.
hanzolo

1
그렇습니다 (GUI). 지금까지 문제가 없었습니다. 4 개 또는 5 개의 다른 프로젝트 / 웹 사이트에서 사용했습니다. 참고 : Fluent NHibernate와 함께 사용합니다. Fluent NHibernate는 config / xml 파일이 아닌 c # 코드로 매핑을 수행합니다. : 여기에 링크의 nmg.codeplex.com
ganders

13

간단한 설명으로 시작하겠습니다. 큰 데이터베이스에 대한 경험이 없으므로 나머지 답변은 실제 예를 기반으로하지 않습니다.

BIG 데이터베이스가 있고 ORM / EF와 함께 사용하려고합니다. 나는 두 번째 선택과 함께 갈 것입니다. 이유는 다음과 같습니다.

  • 매핑은 복잡성을 추가합니다. 현재 응용 프로그램 / 프로젝트 / 모듈이 필요로하지 않는 엔티티와 복잡성을 추가 할 필요는 없지만 세분성을 너무 낮게 만들지는 않습니다. 화면마다 별도의 매핑을 설정해도 도움이되지 않습니다.
  • 작업 단위를 달성하려고합니다. 대부분의 경우 모듈에 필요한 테이블을 지정할 수 있어야합니다 (모든 경우에 필요한 것은 아님). 이러한 테이블을 단일 맵핑 세트에 넣으면 단일 컨텍스트 인스턴스에 의한 읽기 및 데이터 수정을 처리 할 수 ​​있습니다. 이것이 최종 목표가됩니다.
  • 모델이 정확히 무엇을 의미하는지 잘 모르겠지만 다른 매핑 세트를 사용하더라도 동일한 엔티티 유형을 사용하여 매핑 세트간에 클래스를 공유 할 수 있습니다. 따라서 두 개의 모듈에서 User 테이블을 사용하는 경우 동일한 두 개의 User 클래스가 필요하지 않습니다. 여전히 단일 테이블을 사용할 수 있으며 코드 매핑 (일명 코드 우선)의 경우 매핑을 한 번 정의하고 여러 매핑 세트에로드 할 수 있으므로 DRY 원칙을 위반하지 않지만 코드 우선 접근 방식에는 더 많은 제한 사항이 있습니다 뷰 및 저장 프로 시저 EDMX는 이것을 어렵게 만듭니다. 여전히 클래스를 재사용 할 수 있지만 매핑을 재사용 할 수는 없습니다.
  • 교차 모듈 쿼리는 어떻습니까? 이러한 질문은 일어날 수 있지만 정직하게 모든 것이 EF에 의해 처리되어야하는 것은 아닙니다. 일반적인 경우 EF를 활용하여 정기적 인 데이터 액세스를 단순화 할 수 있지만 5 개의 다른 모듈에 속하는 테이블을 조인하는 특수 쿼리가 필요한 경우 직접 실행하거나 저장 프로 시저로 래핑 할 수 있습니다. 기본 데이터 액세스를 100 % 교체하는 것은 어렵고 복잡하며 역효과를 낳을 수 있습니다.
  • 마지막 요점은 단순히 실용적입니다. VS 툴링은 디자이너가 아니라 가져 오기 툴을 사용하지 않고도 이러한 큰 객체 세트로 작업 할 준비가되었다고 생각하지 않습니다. VS2008에서는 기존의 데이터 액세스 및 SQL 데이터베이스 프로젝트를 사용하여 매우 큰 데이터베이스를 작업했습니다. 복잡한 프로젝트의 사용자 경험은 매우 나빴습니다. 사용 된 테이블의 수를 낮게 유지해야합니다. 디자이너의 한도는 100-200 사이 여야하지만 단일 컨텍스트 (매핑 세트)로 처리되는 100 개의 테이블은 한 클래스에 대해 너무 많은 책임을지는 것처럼 들립니다 (100 개의 속성을 설정해야 함 컨텍스트에 노출되면 좋은 디자인처럼 보이지 않습니다).

4

기술적 관점에서 이런 종류의 질문을 결정할 수 없다고 말하고 싶습니다. 사용 사례 (사용자 사례 등)를 기반으로 아키텍처를 구축하는 것이 좋습니다. 먼저 비즈니스 객체를 찾으십시오. 엔티티 오브젝트는 기본적으로 비즈니스 오브젝트가 아닙니다. 일반적으로 엔티티 오브젝트 앞에 비즈니스 오브젝트가 있습니다. 그런 다음 사용자 요구 사항에 따라 실제로 필요한 것을 점진적으로 결정할 수 있습니다.

"좋은 건축가는 내린 결정의 수를 극대화합니다." 로버트시 마틴

http://cleancoder.posterous.com/architecture-deference


3

하이브리드 방식을 사용합니다. OLTP 작업은 EF에서 처리하는 반면 일괄 삽입, 대량 업데이트, 보고서 쿼리 등의 대량 작업은 Stored Procs에서 처리합니다. 또한 데이터 계층을 한 번에 완전히 다시 쓰지 않으면 마이그레이션 경로가 더 쉬워집니다.


이것은 좋은 전략처럼 보이지만 실제로 다른 EF 모델로 엔티티를 나누는 방법에 대한 문제는 다루지 않습니다. 하나의 모델에 모든 엔티티가 있습니까? 아니면 어떤 식 으로든 분할하고 정복합니까?
RationalGeek

1
전체 모델 접근 방식으로 OLTP 성능이 충분하면이를 수행하십시오. 필요한 경우 나중에 나중에 분리 할 수 ​​있지만 가장 빠르고 민첩한 방법은 전체를로드하는 것입니다. 분해하여 성능을 향상시킬 필요가 없으므로 시간을 낭비하고 아무 이유없이 시스템을 더 복잡하게 만들 수 있습니다. 그런 다음 확장하기로 결정할 때 어떤 모델을 새 테이블 / 엔티티에 고정 시킬지에 대한 의문이 있습니다. 여러 모델에서 업데이트를 실행해야 할 경우 어떻게됩니까? 실제로 대안이 없으면 두통을 피하십시오.
Nik

데이터에 액세스 할 때 항상 성능을 조정할 수 있다는 점을 언급하지 않았습니다. 게으른 / 열심히로드 옵션과 가져 오는 하위 엔티티를 살펴보십시오. 대규모 오브젝트 트리를로드하지 않는 경우 전체 모델이 작은 모델보다 더 나쁜 이유는 없습니다.
Nik

대규모 스키마를 처리 할 때는 대규모 객체 트리와 정규화 된 데이터 구조가 필요하다고 생각합니다.
hanzolo

객체 그래프의 채도를 얼마나 적게 또는 얼마만큼 조절할 것인지 제어합니다.
Nik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.