NHibernate와 LINQ to SQL


117

실제 프로젝트에서 두 기술을 모두 사용하지 않은 사람으로서이 두 기술이 서로를 보완하는 방법과 기능이 얼마나 겹치는 지 아는 사람이 있는지 궁금합니다.

답변:


113

LINQ to SQL은 클래스 별 테이블 패턴을 사용하도록합니다. 이 패턴 사용의 이점은 빠르고 쉽게 구현할 수 있으며 기존 데이터베이스 구조를 기반으로 도메인을 실행하는 데 거의 노력이 들지 않는다는 것입니다. 단순한 애플리케이션의 경우 이것은 완벽하게 수용 가능하며 (그리고 종종 더 바람직 함), 더 복잡한 애플리케이션의 경우 개발자는 종종 도메인 기반 디자인 패턴을 사용하도록 제안 합니다 (NHibernate가 용이하게하는 것입니다).

클래스 별 테이블 패턴의 문제점은 데이터베이스 구조가 도메인 디자인에 직접적인 영향을 미친다는 것입니다. 예를 들어 고객의 기본 주소 정보를 보관하기 위해 다음 열이있는 Customers 테이블이 있다고 가정 해 보겠습니다.

  • StreetAddress
  • 시티
  • 상태
  • 지퍼

이제 고객의 우편 주소에 대한 열도 추가하고 Customers 테이블에 다음 열을 추가한다고 가정 해 보겠습니다.

  • MailingStreetAddress
  • 메일 링 시티
  • MailingState
  • MailingZip

LINQ to SQL을 사용하면 도메인의 Customer 개체에 이러한 8 개 열 각각에 대한 속성이 있습니다. 그러나 도메인 기반 디자인 패턴을 따르는 경우 아마도 Address 클래스를 만들고 Customer 클래스에 두 개의 Address 속성 (우편 주소 용 하나와 현재 주소 용 하나)이 포함되었을 것입니다.

이것은 간단한 예이지만 클래스 별 테이블 패턴이 어떻게 다소 냄새 나는 도메인으로 이어질 수 있는지 보여줍니다. 결국 그것은 당신에게 달려 있습니다. 다시 말하지만 기본 CRUD (만들기, 읽기, 업데이트, 삭제) 기능 만 필요한 간단한 앱의 경우 단순성 때문에 LINQ to SQL이 이상적입니다. 그러나 개인적으로 NHibernate를 사용하는 것을 좋아합니다. 왜냐하면 더 깨끗한 도메인을 가능하게하기 때문입니다.

편집 : @lomaxx-예, 제가 사용한 예제는 단순했고 LINQ to SQL에서 잘 작동하도록 최적화되었을 수 있습니다. 나는 요점을 집으로 몰아 가기 위해 가능한 한 기본적으로 유지하고 싶었습니다. 데이터베이스 구조가 도메인 구조를 결정하는 것은 나쁜 생각이거나 최소한 차선의 OO 디자인으로 이어질 수있는 몇 가지 시나리오가 있지만 요점은 남아 있습니다.


4
Linq To SQL을 사용하여 저장소 구현을 코딩 할 수 있습니다. 매우 편리합니다.
Nicolas Dorier

1
ActiveRecord가 아니라고 생각합니다. 매핑 된 클래스도 일부 인프라 로직을 캡슐화합니다. ActiveRecord 패턴은 Customer.Save ()를 가질 수있는 경우입니다. L2S는 nHibernate의 Session과 같이 DataContext 클래스로 작업 단위 패턴을 구현하지만 NH는 실제 POCO 접근 방식을 가지고 있습니다.
Hrvoje Hudo

1
@kevin "LINQ to SQL은 활성 레코드 패턴을 사용합니다."맞지 않습니다. ADO.NET이 활성 레코드를 사용하거나 NHibernate가 활성 레코드를 사용한다고 말하는 것과 같습니다. 이들은 모두 데이터 액세스 기술이며 특정 데이터 액세스 패턴을 적용하지 않습니다. 저는 개인적으로 저장소 패턴과 함께 linq-to-sql을 사용하고 싶습니다. linq-to-sql이 NHibernate와 같은 복잡한 매핑을 지원하지 않는다는 것이 맞습니다.
liammclennan

1
대신 데이터베이스를 정규화하고 SQLMetal과 같은 도구로 DAL을 생성하는 것은 어떻습니까?
Alex

3
@CoffeeAddict 임피던스 불일치가 너무 커서 imo에서 LINQ to SQL을 사용하기에는 애플리케이션이 너무 복잡합니다. 내 예제가 냄새 나는 이유는 LINQ to SQL을 사용하면 2가 아닌 8 개의 속성이 생성되고 Address 클래스를 사용하는 함수를 구현하거나 Address 클래스에서 루틴을 구현하는 등의 작업을 수행 할 수있는 능력이 제한되기 때문입니다. NHibernate를 사용한 경우 수행하십시오.
Kevin Pang

26

지금까지 놓친 두 가지 사항 :

  • LINQ to SQL은 Oracle 또는 SqlServer를 제외한 모든 데이터베이스에서 작동하지 않습니다. 그러나 타사에서는 devArt의 dotConnect , DbLinq , Mindscape의 LightSpeedALinq 등 Oracle에 대한 더 나은 지원을 제공합니다 . (나는 이것들에 대한 개인적인 경험이 없습니다)

  • Linq to NHibernate를 사용하면 Linq를 Nhiberate와 함께 사용할 수 있으므로 사용하지 않는 이유를 제거 할 수 있습니다.

또한 Nhibernate에 대한 새롭고 유창한 인터페이스는 Nhibernate의 매핑을 구성하는 것을 덜 고통스럽게 만드는 것 같습니다. (Nhibernate의 문제점 중 하나 제거)


최신 정보

Linq to Nhiberate는 현재 알파 버전 인 Nhiberate v3에서 더 좋습니다 . Nhiberate v3가 올해 말에 출시 될 것으로 보입니다.

.net 4 의 엔티티 프레임 작업 도 실제 옵션처럼 보이기 시작했습니다.


2
Linq to NHibernate는 아직 초기 단계에 있습니다. 그것은 완전한 구현이 아니며 틀림없이 프로덕션 용도로 전혀 준비되지 않았습니다.
liammclennan

새로운 LinqConnect 2.0 릴리스에는 Table Per Type 상속 지원, PLINQ 지원 및 배치 업데이트 기능과 같은 편의를 위해 몇 가지 추가 기능이 도입되었습니다. ORM Designer (Devart Entity Developer)에는 이제 Model First 지원 및 매핑 동기화 기능이 있습니다. 자세한 내용 : devart.com/news/2010/dotconnects600.html
Devart

23

@Kevin : 당신이 제시하는 예제의 문제는 당신이 열악한 데이터베이스 디자인을 사용하고 있다는 것입니다. 나는 당신이 고객 테이블과 주소 테이블을 만들고 테이블을 정규화 할 것이라고 생각했을 것입니다. 그렇게하면 제안하는 시나리오에 Linq To SQL을 확실히 사용할 수 있습니다. Scott Guthrie는 Linq To SQL 사용에 대한 일련의 훌륭한 게시물을 보유 하고 있습니다.

Linq와 NHibernate가 함께 사용할 수 있다는 것을 의미하므로 서로 보완한다고 말할 수는 없으며 이것이 가능하지만 하나를 선택하고 고수하는 것이 훨씬 낫습니다.

NHibernate를 사용하면 매우 유연한 방식으로 데이터베이스 테이블을 도메인 개체에 매핑 할 수 있습니다. 또한 HBL을 사용하여 데이터베이스를 쿼리 할 수 ​​있습니다.

Linq to SQL을 사용하면 도메인 개체를 데이터베이스에 매핑 할 수도 있지만 Linq 쿼리 구문을 사용하여 데이터베이스를 쿼리합니다.

여기서 가장 큰 차이점은 Linq 쿼리 구문이 컴파일러에서 컴파일 시간에 검사되어 쿼리가 유효한지 확인한다는 것입니다.

linq에서 알아야 할 사항은 .net 3.x에서만 사용할 수 있고 VS2008에서만 지원된다는 것입니다. NHibernate는 VS2005뿐 아니라 2.0 및 3.x에서도 사용할 수 있습니다.

NHibernate에서 알아야 할 사항은 도메인 개체를 생성하지 않으며 매핑 파일도 생성하지 않는다는 것입니다. 이 작업은 수동으로 수행해야합니다. Linq는
이 작업을 자동으로 수행 할 수 있습니다.


15
다른 앱을 지원하기 때문에 변경할 수없는 레거시 데이터베이스 구조에 대해 코드를 작성하는 경우 어떻게해야합니까? 도메인 모델이 열악한 데이터베이스 디자인을 상속하기를 원합니까, 아니면 데이터베이스 구조와 독립적으로 달라질 수있는 풍부한 도메인 모델을 만들고 싶습니까?
Larry Foulkrod

7

Fluent NHibernate는 간단한 규칙을 기반으로 매핑 파일을 생성 할 수 있습니다. XML 작성이없고 강력한 형식입니다.

최근에 성능상의 이유로 Linq에서 SQL로 NHibernate로 변경해야하는 프로젝트에서 작업했습니다. 특히 L2S의 객체 구체화 방식은 NHibernate의 방식보다 느리고 변경 관리도 상당히 느립니다. 그리고 필요하지 않은 특정 시나리오에 대해 변경 관리를 해제하는 것이 어려울 수 있습니다.

예를 들어 WCF 시나리오에서 DataContext에서 연결이 끊어진 엔터티를 사용하려는 경우 변경 사항을 업데이트하기 위해 다시 DataContext에 연결하는 데 많은 문제가있을 수 있습니다. 나는 NHibernate에 문제가 없었습니다.

L2S에서 내가 놓칠 것은 대부분 엔티티의 양쪽 끝에서 관계를 최신 상태로 유지하는 코드 생성입니다. 하지만 NHibernate가 그렇게 할 수있는 몇 가지 도구가 있다고 생각합니다.


2
이런 경우 다른 사람의 게시물을 읽고 너무 점프 선박의 생각 - .ObjectTrackingEnabled = false당신은에 DataContext변경 내용 추적 문제를 해결 한 것이다. 작업 단위 패턴을 구입하고 DDD를 수행하지 않는 한 Linq-to-SQL은 실제로 제공합니다.
mattmc3 2010

" 성능상의 이유로 Linq에서 SQL로 변경해야했습니다. "-NHibernate를 몇 년 동안 사용해 온 것 같습니다. 나는 우리가 대부분 속이고 실제 성능 압력 포인트를 위해 네이티브 SQL을 작성했다고 생각합니다. 마이그레이션이 어떻게 진행되었는지와 그만한 가치가 있는지에 대한 업데이트 (6 년 후 ...)를 듣는 것이 흥미로울 것입니다.
ruffin

5

"LINQ"가 의미하는 바를 명확히 할 수 있습니까?

LINQ는 데이터 액세스 기술이 아니라 기본 구문으로 쿼리를 지원하는 언어 기능 일뿐입니다. 특정 인터페이스 (예 : IQueryable)를 지원하는 모든 개체 모델을 쿼리 할 수 ​​있습니다.

많은 사람들이 LINQ To SQL을 LINQ라고 부르지 만 전혀 정확하지 않습니다. Microsoft는 .NET 3.5 SP1과 함께 LINQ To Entities를 방금 출시했습니다. 또한 NHibernate에는 LINQ 인터페이스가 있으므로 LINQ 및 NHibernate를 사용하여 데이터를 가져올 수 있습니다.


2

LINQ는 LINQ 자체에는 연결된 데이터베이스가 없기 때문에 LINQ to SQL을 의미한다고 가정합니다. SQL처럼 보이게 만드는 구문 설탕이 많은 쿼리 언어 일뿐입니다.

기본적인 예제에서 NHibernate와 LINQ to SQL은 모두 동일한 문제를 해결하는 것 같습니다. 일단 통과하면 NHibernate가 진정으로 풍부한 도메인 모델을 만들 수있는 많은 기능을 지원한다는 것을 곧 알게됩니다. LINQ to SQL을 사용하는 것과 거의 동일한 방식으로 LINQ를 사용하여 NHibernate를 쿼리 할 수있는 LINQ to NHibernate 프로젝트도 있습니다.


1

먼저 두 가지를 분리 해 보겠습니다. 데이터베이스 모델링은 데이터에 관한 것이고 개체 모델링은 엔티티와 관계에 관한 것입니다.

Linq-to-SQL의 장점은 데이터베이스 스키마에서 클래스를 빠르게 생성하여 활성 레코드 개체로 사용할 수 있다는 것입니다 (활성 레코드 디자인 패턴 정의 참조).

NHibernate의 장점은 객체 모델링과 데이터베이스 모델링 간의 유연성을 허용하는 것입니다. 예를 들어 성능을 고려하여 데이터를 가장 잘 반영하도록 데이터베이스를 모델링 할 수 있습니다. 개체 모델링은 Domain-Driven-Design과 같은 접근 방식을 사용하여 비즈니스 규칙의 요소를 가장 잘 반영합니다. (Kevin Pang 주석 참조)

모델링 및 / 또는 명명 규칙이 좋지 않은 레거시 데이터베이스를 사용하면 Linq-to-SQL이 원하지 않는 구조와 이름을 클래스에 반영합니다. 그러나 NHibernate는 데이터 매퍼로 이러한 혼란을 숨길 수 있습니다.

데이터베이스의 이름 지정이 좋고 복잡성이 낮은 그린 필드 프로젝트에서는 Linq-to-SQL이 좋은 선택이 될 수 있습니다.

그러나 Fluent NHibernate 를 규칙과 같은 매핑과 동일한 목적으로 자동 매핑과 함께 사용할 수 있습니다 . 이 경우 XML 또는 C #을 사용하는 데이터 매퍼에 대해 걱정하지 않고 NHibernate가 사용자 정의 할 수있는 규칙을 기반으로 엔티티에서 데이터베이스 스키마를 생성하도록합니다.

반면 Linq-to-SQL의 학습 곡선은 NHibernate보다 작습니다.


0

또는 Castle ActiveRecords 프로젝트를 사용할 수 있습니다. 나는 레거시 프로젝트를위한 새로운 코드를 만들기 위해 짧은 시간 동안 그것을 사용 해왔다. 그것은 NHibernate를 사용하고 활성 레코드 패턴에서 작동합니다 (내가 아는 이름을 감안할 때 놀랍습니다). 나는 시도하지 않았지만 일단 사용했다면 NHibernate 지원으로 직접 내려야 ​​할 필요성을 느낀다면 프로젝트의 일부 또는 전부를 그렇게하는 것이 너무 많지 않을 것이라고 가정합니다.


0

"둘 중 하나도 사용하지 않은 사람을 위해"라고 썼 듯이 LINQ to SQL은 사용하기 쉬우므로 누구나 쉽게 사용할 수 있습니다. 또한 대부분의 시간에 도움이되는 프로 시저를 지원합니다. 두 개 이상의 테이블에서 데이터를 가져온 다음 프로 시저를 작성하고 해당 프로 시저를 디자이너로 끌어다 놓으면 모든 것이 생성됩니다. 프로 시저 이름이 "CUSTOMER_ORDER_LINEITEM"이라고 가정하면이 세 테이블 모두에서 레코드를 가져온 다음 작성하면됩니다.

MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();

NHibernate에서 지원하지 않는 foreach 루프에서도 레코드 객체를 사용할 수 있습니다.

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