소개
.NET 세계에서 데이터베이스에 액세스하는 데 가장 많이 사용되는 방법 중 하나는 언어 구문과 긴밀하게 통합된 ORM(객체 관계형 매퍼)인 EF(Entity Framework)를 사용하는 것입니다. .NET 언어에 기본으로 제공되는 LINQ(Language Integrated Queries)를 사용하면 SQL에 대한 지식이 없어도 일반 .NET 컬렉션을 사용하여 작업하는 것처럼 데이터에 액세스할 수 있습니다. 여기에는 장점과 단점이 있으므로 여기서는 언급하지 않으려고 합니다. 그러나 지속적으로 발생하는 문제 중 하나는 소프트웨어 프로젝트의 구조, 추상화 수준 및 궁극적으로 단위 테스트와 관련된 혼란입니다.
이 게시물에서는 저장소 추상화가 항상 유용한 이유를 설명하려고 합니다. 많은 사람들이 추상화된 데이터 액세스에 대한 용어로 저장소를 사용하는 반면, 유사한 것과 관련된 저장소 소프트웨어 패턴도 있지만 동일한 것은 아닙니다. 여기에서는 저장소를 데이터 액세스의 구현 세부 사항을 추상화하는 일련의 인터페이스라고 부르고 디자인 패턴을 완전히 무시하겠습니다.
역사
알고 계시다면 건너뛰셔도 됩니다. 하지만 먼저 저장소에 대한 아이디어를 어떻게 얻게 되었는지부터 설명해야 합니다.
선사시대에는 코드가 구조 없이 모든 내용을 담고 있는 그대로 작성되었으며, 원하는 대로 또는 적어도 바라는 대로 수행되었습니다. 자동화된 테스트는 없었고 작동할 때까지 수동으로 해킹하고 테스트했습니다. 각 애플리케이션은 코드 구조, 재사용 또는 가독성보다 하드웨어 요구 사항이 더 중요하다는 점을 고려하여 현재 사용 가능한 모든 방식으로 작성되었습니다. 그게 공룡을 죽인 이유야! 사실입니다.
천천히 패턴이 나타나기 시작했습니다. 특히 비즈니스 애플리케이션의 경우 비즈니스 코드, 데이터 지속성 및 사용자 인터페이스가 명백히 분리되었습니다. 이를 레이어라고 부르며 곧 서로 다른 프로젝트로 분리되었습니다. 이는 서로 다른 관심사를 다루었을 뿐만 아니라 이를 구축하는 데 필요한 기술이 특히 달랐기 때문입니다. UI 디자인은 코드 로직 작업과 매우 다르며 SQL이나 데이터를 유지하는 데 사용된 언어나 시스템과도 매우 다릅니다.
따라서 비즈니스와 데이터 계층 간의 상호작용은 인터페이스와 모델로 추상화하여 이루어졌습니다. 비즈니스 클래스에서는 테이블의 항목 목록을 요청하지 않고 필터링된 복잡한 개체 목록이 필요합니다. 지속되는 모든 것에 액세스하고 이를 비즈니스가 이해할 수 있는 항목에 매핑하는 것은 데이터 계층의 책임입니다. 이러한 추상화는 저장소라고 불리기 시작했습니다.
데이터 액세스의 하위 계층에서는 CRUD와 같은 패턴이 빠르게 자리를 잡았습니다. 테이블과 같은 구조화된 지속성 컨테이너를 정의하고 레코드를 생성, 읽기, 업데이트 또는 삭제했습니다. 코드에서 이러한 종류의 논리는 목록, 사전 또는 배열과 같은 컬렉션으로 추상화됩니다. 따라서 리포지토리는 컬렉션처럼 작동해야 하며 실제 생성, 읽기, 업데이트 및 삭제 외에는 다른 방법이 없을 만큼 충분히 일반적이어야 한다는 의견도 있었습니다.
그러나 저는 이에 동의하지 않습니다. 비즈니스로부터의 데이터 액세스 추상화로서, 비즈니스 요구 사항을 기반으로 모델링하는 대신 데이터 액세스 패턴에서 최대한 멀리 떨어져야 합니다. 특히 Entity Framework의 사고방식과 다른 많은 ORM이 저장소의 원래 아이디어와 충돌하기 시작하여 EF에서 저장소를 절대 사용하지 말라는 요청으로 끝나고 이를 안티패턴이라고 부르는 지점이 있습니다.
더 많은 레이어
모델 간의 부모-자식 관계로 인해 많은 혼란이 발생합니다. 사람이 포함된 부서 엔터티와 같습니다. 부서 저장소는 사람이 포함된 모델을 반환해야 합니까? 어쩌면 그렇지 않을 수도 있습니다. 그렇다면 저장소를 부서(사람 제외)와 사람으로 분리한 다음 비즈니스 모델에 매핑할 별도의 추상화를 갖는 것은 어떨까요?
비즈니스 계층을 하위 계층으로 분리하면 실제로 혼란이 커집니다. 예를 들어, 대부분의 사람들이 비즈니스 서비스라고 부르는 것은 특정 비즈니스 논리를 특정 유형의 비즈니스 모델에만 적용하는 추상화입니다. 앱이 사람과 함께 작동하므로 Person이라는 모델이 있다고 가정해 보겠습니다. 사람을 처리하는 클래스는 PeopleRepository를 통해 지속성 계층에서 비즈니스 모델을 가져오는 PeopleService가 될 것이지만 데이터 모델과 비즈니스 모델 간의 매핑 또는 사람과 관련된 특정 작업(예: 계산)을 포함하여 다른 작업도 수행합니다. 급여. 그러나 대부분의 비즈니스 로직은 여러 유형의 모델을 사용하므로 서비스는 추가 책임 없이 저장소에 래퍼를 매핑하게 됩니다.
이제 EF를 사용하여 데이터에 액세스한다고 상상해 보세요. SQL 테이블에 매핑하는 엔터티 컬렉션을 포함하는 DbContext 클래스를 이미 선언해야 합니다. LINQ를 사용하면 이를 반복, 필터링 및 매핑할 수 있으며, 이는 백그라운드에서 효율적으로 SQL 명령으로 변환되어 계층적 부모-자식 구조로 완성된 필요한 정보를 제공합니다. 이러한 변환은 특정 열거형이나 이상한 데이터 구조와 같은 내부 비즈니스 데이터 유형의 매핑도 처리합니다. 그렇다면 리포지토리나 서비스가 왜 필요한가요?
더 많은 추상화 계층이 무의미한 오버헤드처럼 보일 수 있지만 프로젝트에 대한 인간의 이해를 높이고 변화의 속도와 품질을 향상한다고 믿습니다. 분명히 균형이 있습니다. 모든 소프트웨어 디자인 패턴이 모든 곳에서 사용되어야 한다는 명백한 요구 사항으로 설계된 시스템을 본 적이 있습니다. 추상화는 코드 가독성과 문제 분리를 향상시키는 경우에만 유용합니다.
이유
EF가 번거로워지는 상황 중 하나는 단위 테스트입니다. DbContext는 많은 노력을 들여 수동으로 모의해야 하는 종속성이 많은 복잡한 시스템입니다. 따라서 Microsoft는 메모리 데이터베이스 공급자라는 아이디어를 내놓았습니다. 따라서 무엇이든 테스트하려면 메모리 데이터베이스를 사용하고 작업을 완료하면 됩니다.
Microsoft 페이지에서는 이 테스트 방법이 이제 "권장되지 않음"으로 표시됩니다. 또한 이러한 예에서도 EF는 리포지토리에 의해 추상화됩니다.
메모리 데이터베이스 테스트가 작동하는 동안 해결하기 쉽지 않은 몇 가지 문제가 추가됩니다.
- 메모리 내 DbContext를 설정하려면 기존 엔터티에 대한 모든 종속성이 필요합니다
- 각 테스트에 대한 메모리 데이터베이스 설정 및 시작이 느립니다
- 유효한 데이터베이스 출력을 얻으려면 원자적으로 테스트하려는 것보다 훨씬 더 많은 것을 설정해야 합니다
따라서 결국 사람들은 "도우미" 메서드 내에서 데이터베이스의 모든 것을 설정한 다음 이 불가해하고 복잡한 메서드로 시작하여 가장 작은 기능까지 테스트하는 테스트를 생성하게 됩니다. EF 코드가 포함된 모든 코드는 이 설정 없이는 테스트할 수 없습니다.
따라서 리포지토리를 사용하는 한 가지 이유는 테스트 추상화를 DbContext 위로 이동하는 것입니다. 이제 데이터베이스가 전혀 필요하지 않고 저장소 모의만 필요합니다. 그런 다음 실제 데이터베이스를 사용하여 통합 테스트에서 저장소 자체를 테스트하십시오. 인메모리 데이터베이스는 실제 데이터베이스와 매우 유사하지만 조금 다릅니다.
실생활에서 실제 가치가 거의 없다고 인정하는 또 다른 이유는 데이터에 액세스하는 방식을 변경하고 싶을 수도 있다는 것입니다. 어쩌면 NoSql이나 일부 메모리 분산 캐시 시스템으로 변경하고 싶을 수도 있습니다. 또는 모놀리식 데이터베이스와 같은 데이터베이스 구조로 시작하여 이제 이를 다양한 테이블 구조를 가진 여러 데이터베이스로 리팩터링하려고 할 가능성이 훨씬 높습니다. 리포지토리 없이는 불가능하다는 점을 즉시 말씀드리겠습니다.
그리고 Entity Framework의 경우, 얻는 엔터티는 데이터베이스에 매핑된 활성 레코드입니다. 하나를 변경하고 다른 항목의 변경 사항을 저장하면 갑자기 첫 번째 엔터티도 DB에서 업데이트됩니다. 아니면 내용을 포함하지 않았거나 맥락이 바뀌어서 포함하지 않았을 수도 있습니다.
EF 지지자들은 항상 엔터티 추적을 매우 긍정적인 것으로 과장합니다. 데이터베이스에서 엔터티를 가져와 비즈니스를 수행한 다음 엔터티를 업데이트하고 저장한다고 가정해 보겠습니다. 리포지토리를 사용하면 데이터를 얻은 다음 비즈니스를 수행한 다음 약간의 업데이트를 수행하기 위해 데이터를 다시 가져옵니다. EF는 이를 메모리에 유지하고 변경 전에 업데이트되지 않았다는 것을 알고 있으므로 두 번 읽지 않습니다. 그것은 사실이다. 이는 데이터베이스 변경 사항을 어떻게든 인식하고 데이터베이스에서 처리하는 모든 것을 추적하는 데이터베이스용 메모리 캐시를 설명합니다. 달리 지시하지 않는 한 데이터베이스 항목을 복잡한 C# 엔터티에 양방향으로 매핑하고 변경 사항을 앞뒤로 추적하는 동시에 깊이 내장되어 있습니다. 비즈니스 코드에서. 개인적으로 나는 이러한 과도한 책임과 우려사항 분리의 부족이 이를 사용하여 얻은 어떤 성과보다 훨씬 더 해롭다고 생각합니다. 게다가, 약간의 초기 노력을 통해 비즈니스, 캐싱 및 데이터 액세스 간의 명확한 경계를 유지하면서 모든 기능을 저장소 또는 저장소에 대한 또 다른 메모리 캐싱 계층에서 추상화할 수 있습니다.
사실 이 모든 것에서 실제로 어려운 점은 별도의 관심사를 가져야 하는 시스템 간의 경계를 결정하는 것입니다. 예를 들어, 필터링 논리를 데이터베이스의 저장 프로시저로 이동하면 많은 성능을 얻을 수 있지만, 사용된 알고리즘의 테스트 가능성과 가독성이 손실됩니다. 반대로 EF 또는 다른 메커니즘을 사용하여 모든 논리를 코드로 이동하는 것은 성능이 떨어지고 때로는 실행 불가능합니다. 아니면 데이터 개체가 비즈니스 개체가 되는 지점은 어디입니까(위의 부서 및 사람 예 참조)?
아마도 가장 좋은 전략은 먼저 이러한 경계를 정의한 다음 어떤 기술과 디자인이 거기에 적합할지 결정하는 것입니다.
내 결론
저는 저장소가 Entity Framework 또는 기타 ORM을 사용하더라도 서비스 및 저장소 추상화를 항상 사용해야 한다고 믿습니다. 그것은 모두 우려 사항의 분리로 귀결됩니다. 나는 Entity Framework를 유용한 소프트웨어 추상화라고 생각하지 않습니다. 왜냐하면 너무 많은 짐이 있기 때문입니다. 따라서 코드에서 이를 추상화하는 데 저장소가 많이 사용됩니다. EF는 유용한 추상화이지만 소프트웨어가 아닌 데이터베이스 액세스용입니다.
내 소프트웨어 작성 철학은 애플리케이션 요구 사항부터 시작하여 해당 요구 사항에 맞는 구성 요소를 만들고 인터페이스를 통해 하위 수준 기능을 추상화하는 것입니다. 그런 다음 다음 수준에서 프로세스를 반복하여 항상 코드를 읽을 수 있는지 확인하고 현재 수준에서 사용되는 구성 요소나 사용되는 구성 요소를 이해할 필요가 없는지 확인합니다. 그렇지 않다면 우려 사항을 잘못 분리한 것입니다. 따라서 비즈니스 애플리케이션에는 특정 데이터베이스나 ORM을 사용해야 하는 요구 사항이 없었으므로 데이터 계층 추상화는 이에 대한 모든 지식을 숨겨야 합니다.
기업이 원하는 것은 무엇입니까? 필터링된 사람들 목록이요? var people = service.GetFilteredListOfPeople(filter); 그 이상도 그 이하도 아닙니다. 서비스 메소드는 return mapPeople(repo.GetFilteredListOfPeople(mappedFilter)); 다시 말하지만 그 이상도 그 이하도 아닙니다. 저장소가 어떻게 사람들을 구하고, 사람들을 구하고, 다른 일을 하는지는 서비스의 관심사가 아닙니다. 캐싱을 원하는 경우 IPeopleRepository를 구현하고 IPeopleRepository에 대한 종속성을 갖는 일부 캐싱 메커니즘을 구현합니다. 매핑을 원하면 올바른 IMapper 인터페이스를 구현하십시오. 등등.
이 기사에서는 지나치게 장황한 내용을 다루지 않았으면 좋겠습니다. 이는 소프트웨어 문제가 아니라 개념적 문제에 가깝기 때문에 특별히 코드 예제를 제외했습니다. Entity Framework가 여기에서 제가 불만을 제기하는 대부분의 대상일 수 있지만 이는 작은 일에서는 마술처럼 도움이 되지만 중요한 일을 망가뜨리는 모든 시스템에 적용됩니다.
도움이 되었기를 바랍니다!
위 내용은 ORM을 사용해도 리포지토리를 사용하여 코드로 데이터 액세스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

C는 현대 세계에서 널리 사용되고 중요합니다. 1) 게임 개발에서 C는 Unrealengine 및 Unity와 같은 고성능 및 다형성에 널리 사용됩니다. 2) 금융 거래 시스템에서 C의 낮은 대기 시간과 높은 처리량은 고주파 거래 및 실시간 데이터 분석에 적합한 첫 번째 선택입니다.

C : Tinyxml-2, Pugixml, XERCES-C 및 RapidXML에는 4 개의 일반적으로 사용되는 XML 라이브러리가 있습니다. 1. TINYXML-2는 자원이 제한적이고 경량이지만 제한된 기능을 가진 환경에 적합합니다. 2. PugixML은 빠르며 복잡한 XML 구조에 적합한 XPath 쿼리를 지원합니다. 3.xerces-c는 강력하고 DOM 및 SAX 해상도를 지원하며 복잡한 처리에 적합합니다. 4. RapidXML은 성능에 중점을두고 매우 빠르게 구문 분석하지만 XPath 쿼리를 지원하지는 않습니다.

C는 XML과 타사 라이브러리 (예 : TinyXML, Pugixml, Xerces-C)와 상호 작용합니다. 1) 라이브러리를 사용하여 XML 파일을 구문 분석하고 C- 처리 가능한 데이터 구조로 변환하십시오. 2) XML을 생성 할 때 C 데이터 구조를 XML 형식으로 변환하십시오. 3) 실제 애플리케이션에서 XML은 종종 구성 파일 및 데이터 교환에 사용되어 개발 효율성을 향상시킵니다.

C#과 C의 주요 차이점은 구문, 성능 및 응용 프로그램 시나리오입니다. 1) C# 구문은 더 간결하고 쓰레기 수집을 지원하며 .NET 프레임 워크 개발에 적합합니다. 2) C는 성능이 높고 시스템 프로그래밍 및 게임 개발에 종종 사용되는 수동 메모리 관리가 필요합니다.

C#과 C의 역사와 진화는 독특하며 미래의 전망도 다릅니다. 1.C는 1983 년 Bjarnestroustrup에 의해 발명되어 객체 지향 프로그래밍을 C 언어에 소개했습니다. Evolution 프로세스에는 자동 키워드 소개 및 Lambda Expressions 소개 C 11, C 20 도입 개념 및 코 루틴과 같은 여러 표준화가 포함되며 향후 성능 및 시스템 수준 프로그래밍에 중점을 둘 것입니다. 2.C#은 2000 년 Microsoft에 의해 출시되었으며 C와 Java의 장점을 결합하여 진화는 단순성과 생산성에 중점을 둡니다. 예를 들어, C#2.0은 제네릭과 C#5.0 도입 된 비동기 프로그래밍을 소개했으며, 이는 향후 개발자의 생산성 및 클라우드 컴퓨팅에 중점을 둘 것입니다.

C# 및 C 및 개발자 경험의 학습 곡선에는 상당한 차이가 있습니다. 1) C#의 학습 곡선은 비교적 평평하며 빠른 개발 및 기업 수준의 응용 프로그램에 적합합니다. 2) C의 학습 곡선은 가파르고 고성능 및 저수준 제어 시나리오에 적합합니다.

C# 및 C가 객체 지향 프로그래밍 (OOP)의 구현 및 기능에 상당한 차이가 있습니다. 1) C#의 클래스 정의 및 구문은 더 간결하고 LINQ와 같은 고급 기능을 지원합니다. 2) C는 시스템 프로그래밍 및 고성능 요구에 적합한 더 미세한 입상 제어를 제공합니다. 둘 다 고유 한 장점이 있으며 선택은 특정 응용 프로그램 시나리오를 기반으로해야합니다.

XML에서 C로 변환하고 다음 단계를 통해 수행 할 수 있습니다. 1) TinyxML2 라이브러리를 사용하여 XML 파일을 파싱하는 것은 2) C의 데이터 구조에 데이터를 매핑, 3) 데이터 운영을 위해 std :: 벡터와 같은 C 표준 라이브러리를 사용합니다. 이러한 단계를 통해 XML에서 변환 된 데이터를 효율적으로 처리하고 조작 할 수 있습니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Dreamweaver Mac版
시각적 웹 개발 도구

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는
