데이터 액세스 계층 내의 비즈니스 개체


12

그래서 저는 TDD를 통해 데이터 액세스 계층을 만들었고 다소 우려에 접근했습니다. 차라리 잘못된 길을 시작하지 않기 위해 여러분들에게 내 생각이 깨끗한 건축물과 일치하는지 물어 보라고 생각했습니다.

내 데이터 액세스 계층 (DAL)의 방법은 매우 간단합니다. 그것들은 데이터베이스의 저장 프로 시저와 일치하며 (정리를 유지하기 위해 다른 방법으로 호출하지 않음) 프로 시저와 동일한 매개 변수를 포함합니다. 그런 다음 데이터베이스에 연결하고 쿼리 결과를 반환합니다. 예를 들면 다음과 같습니다.

public int DeleteRecord(int recordId)
{
    recordId.RequireThat("recordId").NotZeroOrLess();

    List<SqlParameter> parameters = new List<SqlParameter>();
    parameters.Add(new SqlParameter { ParameterName = "@RecordId", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = recordId});

    return this.ExecuteNonQuery("DeleteRecord", parameters.ToArray());
}

결과 집합에서 의미있는 작업을 수행하지 않기 때문에이 유형의 방법에 완벽하게 작동합니다. 명령이 작동하는지 확인하고 싶기 때문에 영향을받는 행 인 비 쿼리의 결과를 반환하고 해당 숫자를 사용하여 논리를 확인할 수 있습니다.

그러나 다른 DAL 방법에서는 레코드를로드하고 싶습니다. 내 부하 절차를 수행 할 것입니다 selects테이블의 무리와 반환에 대해 DataSet,하지만 난 비즈니스를 만들어야 내 DAL은을 사용하는 방법 내에서 개체 여부와 싸우고 있어요 DataSet, 또는 내 비즈니스 개체 경우 스스로 그냥해야 Load()을 얻는 방법을 DataSetDAL에서 기본적으로 채워집니다.

DAL을 통해이를 수행하면 Business Objects에서 논리가 줄어들게됩니다 (이것은 단지 논리 일 뿐이지 만 여전히 논리 임). 하지 마라.

너희들은 어떻게 생각하니?


Entity Framework를 사용하지 않은 이유는 무엇입니까?
jfrankcarr 2012

@jfrankcarr-솔직히 말하면, 주로 익숙하지 않기 때문에 정직합니다. 그러나 Entity Framework가 관계를 올바르게 인식 할 수 있도록 테이블을 다시 작업하고 적절한 외래 키 등을 추가해야합니다. 그러나 호기심을 피하기 위해 Business Objects 자체와 함께 프레임 워크를 사용하여 모든 선택을 수행합니까, 아니면 LINQ 쿼리를 어디에 둘 것인지에 대한 결정이 여전히 있습니까?

시간을내어 EF를 배우는 것이 좋습니다. 특히 기존 디자인 문제가있는 기존 데이터베이스에 맞추려고 할 때 처음에는 약간 어려워 보일 수 있지만 그만한 가치가 있습니다.
jfrankcarr

다른 옵션을 찾고 싶다면 NHibernate를 볼 수도 있습니다.
Don 01001100

@jfrankcarr-확실히 살펴볼 것이지만 다중 계층 데이터 액세스 응용 프로그램과 어떻게 맞습니까? 엔터티 프레임 워크 자체가 DAL 자체 또는 다른 계층 또는 비즈니스 오브젝트 자체 내에 구현됩니까?

답변:


4

DAL은 데이터 개체를 반환해야합니다

응용 프로그램 코드가 데이터 개체를 요청하거나 기존 데이터 개체를 조작하는 데 사용할 수있는 "블랙 박스"개체가 이상적입니다. 때로는 DAL과 응용 프로그램 코드 사이에 또 ​​다른 계층이 있으며이 Repository계층이 항상 필요한 것은 아니지만 두 계층을 더 분리합니다.

또한 일반적으로 비즈니스 오브젝트가 자신을 작성할 수있는 것을 원하지 않습니다. 이로 인해 누군가 라이브러리를 사용할 수있는 보안 허점이 생길 수 있으며 호출하여 객체의 새 인스턴스를 생성 .Load(someId)할 수 있으며 완전히 분리되어야하는 두 개의 레이어를 병합합니다.

.Load(DataSet ds)데이터 세트 정의가 변경되면 해당 데이터 세트를 사용하는 데이터 오브젝트를 찾아서 변경해야하므로 메소드를 제공하지 않는 것이 좋습니다 . 모든 데이터 액세스 코드를 한 곳에 보관하는 것이 더 쉬우므로 데이터 액세스 쿼리를 변경하는 경우 DAL 계층 만 변경하면됩니다.


"올바른 객체"의 정의가 다른 레이어에있는 경우 한 레이어가 어떻게 "올바른 객체를 반환"하는지에 대해 확실하지 않습니다.
TMN

@TMN 그 말이 잘못되었습니다. 나는 당신이 옳기 때문에 문구를 조금 변경했습니다. 앱 코드는 어떤 종류의 객체를 요구하는지 알아야합니다.
Rachel

@Rachel-잡았다. 따라서 DAL이 내 Business Object 자체의 인스턴스를 반환하도록하는 것이 좋습니다. 맞습니까? "데이터 객체"라는 말로 혼란 스러웠지만 이해한다고 생각합니다. 그런 식으로 내 코드는 전화를 걸어서 필요에 따라 비즈니스 객체를 요청할 수 BusinessObject bo = DAL.LoadRecord(id);있습니다. 쿼리를 BO 자체에 매핑하는 논리는 DAL 내에 포함되어 있습니다.

1
나는 같은 DAL 방법 뭔가 이름을 받겠지만 그 @Scott, 맞습니다 Get대신 Load같은Customer c = DAL.GetCustomer(id);
레이첼

2

LINQ-To-SQL 및 Entity Framework 이전에도 필자의 방법은 앱의 여러 계층 간 통신을위한 "작성된 계약"을 제공하는 인터페이스 및 추상 클래스 라이브러리를 사용하는 것이 었습니다. 이를 작업 도메인에 대한 정의 인 온톨로지 라고도 합니다. 레이어 사이를 통과 한 모든 것이이 '계약'을 사용했습니다.

원시 데이터 집합 개체를 데이터 계층에서 비즈니스 계층으로 전달하는 아이디어가 마음에 들지 않습니다. 특히 레거시 데이터 소스를 통합 할 때이 결과로 인해 많은 문제가 발생했습니다. 또한 새로운 사람들이 프로젝트의 데이터를 어디에서 오는지 이해하기가 매우 어려울 수 있습니다. 마지막으로, 비즈니스 계층이 DB에서 직접 데이터를 처리하는 비즈니스에 있어야하므로 복잡한 문제가 발생할 수 있습니다.

예제 코드는 LINQ 이전의 코드와 유사합니다. DAL 객체 내에서 사용하는 공통 DB 함수 클래스가 있습니다. DAL 클래스는 데이터를 읽고 '계약'개체에 맞 춥니 다. 삭제 예제와 같은 스칼라 결과는 일반적으로 부울 값을 반환합니다.


1
"데이터 계층에서 비즈니스 계층으로 원시 데이터 집합 개체를 전달한다는 아이디어가 마음에 들지 않습니다." 이. 천 번 이요
Joshua Smith

@jfrankcarr-내 DAL은 실제로 인터페이스를 구현하며 레이어에서 레이어로 데이터를 전송하는 모든 것에 대한 인터페이스를 계획하고 있으므로 패턴 아이디어가 일치한다고 생각합니다. 따라서 ExecuteScalar쿼리 의 직접 결과를 반환하는 메서드를 비즈니스 계층에 더 적합한 값을 반환하도록 변경하는 것이 좋습니다 bool. 나는 그렇지 않다고 생각합니다. 이것은 Rachel의 대답과 매우 비슷합니다.

영향을받는 레코드 수가 필요하지 않은 경우 일반적으로 작성 / 업데이트 / 삭제 호출 부울을 반환합니다. 예를 들어, 저장된 proc이 여러 주문 라인 또는 이와 유사한 것을 처리하는 경우 int를 반환 할 수 있습니다.
jfrankcarr

0

DAL이 데이터 세트를 반환해야합니다. 반환 된 Dataset은 buisness 객체 여야하며 예상되는 데이터가 있는지 확인하는 것 외에는 수행 할 작업이 없습니다. 더 많은 작업을 수행해야하는 경우 단일 저장 프로 시저에서 너무 많은 작업을 수행하려고하거나 저장 프로 시저에서 데이터를 올바르게 리턴하지 않습니다.


0

비즈니스 개체에는 결과 집합에서 자신을 채울 수있는 생성자가있는 것이 좋습니다. 이렇게하면 DAL과 비즈니스 계층 간의 연결이 제거됩니다. 두 개를 완전히 분리하려면 결과 세트에서 열 이름 => 값 쌍의 간단한 맵을 작성하여 생성자에 전달하십시오.

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