2011-03-28 3 views
1

저는 저장 프로 시저에서 데이터 접근 계층을 수동으로 생성합니다. Linq to SQL 또는 엔티티 프레임 워크를 정상적인 계획에 맞춰야하는 곳을 이해하려고합니다. 나는 일반적으로 DAL 계층에서 비즈니스 계층을 분리하고 inbetween 저장소를 사용합니다.Entity Framework/Linq에서 비즈니스 모델에 이르는 SQL 모델

사람들은 linq에서 생성 된 클래스를 사용하거나 부분 클래스를 사용하여 확장하거나 완전한 분리를 수행하고 생성 된 linq 클래스를 별도의 비즈니스 엔티티에 매핑합니다. 나는 분리 된 사업체의 일부 다. 그러나 이것은 반 직관적 인 것처럼 보입니다.

마지막 프로젝트 중 하나는 DDD와 엔티티 프레임 워크를 사용했습니다. 개체를 침입 할 필요가있을 때 비즈니스 엔터티를 DAL 계층에 갈 때 컨텍스트를 생성하고 개체를 다시 쿼리하는 repistory 계층으로 이동했습니다. 그것은 가치와 부활을 갱신 할 것입니다.

데이터 컨텍스트가 저장되지 않았으므로 큰 점을 보지 못했고 업데이트하기 전에 개체를 가져올 추가 쿼리가 필요했습니다. 는 비즈니스 엔티티로 생성 된 클래스를 SQL로 LINQ를 분리해서하는 것은 의미가 있습니까

  1. : (동시성이 문제가 아닌 경우) 일반적으로 그냥

    그래서 제 질문은 아래에 와서 업데이트를 할 것인가?

  2. 데이터 컨텍스트를 저장해야합니까? 아니면 비실용적입니까?

시간을내어 이해해 주셔서 감사합니다. 나는 더 작은 porjects에서조차 그것을 이해하기 위하여 더 청결한 그것을 만들기 때문에 일반적으로 분리하는 것을 좋아한다.

답변

3

저는 현재 Linq에서 Sql으로 자동 생성 된 코드 파일을 사용하는 대신 직접 Dto 클래스와 Datacontext를 사용합니다. 내 솔루션 아키텍처/모델링에 대한 배경 지식을 얻기 위해 "계약"프로젝트와 "달"프로젝트가 있습니다. (또한 "모델"프로젝트이지만 Dal에만 초점을 맞추려고 노력할 것입니다.) 내 자신의 Dtos와 Datacontext를 손으로 돌려서 모든 것을 훨씬 작고 단순하게 만들었습니다. 여기서 내가 어떻게하는지 몇 가지 예를 들려 드리겠습니다.

나는 Dal의 외부에서 Dto 객체를 반환하지 않습니다. 사실 나는 그것들을 내부로 선언해야합니다. 내가 그들을 반환하는 방법은 인터페이스로 (인터페이스가 내 "계약"계층에 위치 함) 그들을 캐스팅하는 것입니다. 우리는 "IPersonRetriever와 IPersonSaver"인터페이스를 구현하는 간단한 "PersonRepository"를 만들 것입니다.

계약 :

public interface IPersonRetriever 
{ 
    IPerson GetPersonById(Guid personId); 
} 

public interface IPersonSaver 
{ 
    void SavePerson(IPerson person); 
} 

달 :

public class PersonRepository : IPersonSaver, IPersonRetriever 
    { 
     private string _connectionString; 

     public PersonRepository(string connectionString) 
     { 
      _connectionString = connectionString; 
     } 

     IPerson IPersonRetriever.GetPersonById(Guid id) 
     { 
      using (var dc = new PersonDataContext(_connectionString)) 
      { 
       return dc.PersonDtos.FirstOrDefault(p => p.PersonId == id); 
      } 
     } 

     void IPersonSaver.SavePerson(IPerson person) 
     { 
      using (var dc = new PersonDataContext(_connectionString)) 
      { 
       var personDto = new PersonDto 
       { 
        Id = person.Id, 
        FirstName = person.FirstName, 
        Age = person.Age 
       }; 

       dc.PersonDtos.InsertOnSubmit(personDto); 
       dc.SubmitChanges(); 
      } 
     } 
    } 

PersonDataContext :

internal class PersonDataContext : System.Data.Linq.DataContext 
    { 
     static MappingSource _mappingSource = new AttributeMappingSource(); // necessary for pre-compiled linq queries in .Net 4.0+ 

     internal PersonDataContext(string connectionString) : base(connectionString, _mappingSource) { } 

     internal Table<PersonDto> PersonDtos { get { return GetTable<PersonDto>(); } } 
    } 

    [Table(Name = "dbo.Persons")] 
    internal class PersonDto : IPerson 
    { 
     [Column(Name = "PersonIdentityId", IsPrimaryKey = true, IsDbGenerated = false)] 
     internal Guid Id { get; set; } 

     [Column] 
     internal string FirstName { get; set; } 

     [Column] 
     internal int Age { get; set; } 

     #region IPerson implementation 

     Guid IPerson.Id { get { return this.Id; } } 
     string IPerson.FirstName { get { return this.FirstName; } } 
     int IPerson.Age { get { return this.Age; } } 

     #endregion 
    } 

당신은, 당신의 DTO의 모든 속성에 "열"속성을 추가해야하지만 경우 인터페이스에서와 같이 필드를 노출하려는 대상과 일대일 상관 관계가있는 경우 실제 테이블 컬럼의 이름이면 Named Parameters를 추가 할 필요가 없습니다. 이 예제에서 데이터베이스의 PersonId는 "PersonIdentityId"로 저장되지만, 필자의 인터페이스에서 "Id"라고 말하는 필드 만 만들면됩니다.

내가 Dal 레이어를 어떻게 사용하는지,이 레이어는 멍청하고 실제 바보 같아야한다고 생각합니다. CRUD (Create, Retrieve, Update 및 Delete) 작업에만 해당된다는 의미에서 바보입니다.모든 비즈니스 로직은 IPersonSaver 및 IPersonRetriever 인터페이스를 사용하고 사용하는 "모델"프로젝트에 포함됩니다.

희망이 도움이됩니다.

+0

훨씬 더 의미가 있습니다. 나는 가지고있는 질문, 이것이 자동 생성 클래스의 기능을 어떻게 활용합니까? 그것은 좋은 seperation을 가지고 싶다면 여전히 할 배관의 좋은 금액이있는 것 같습니다. – Aur

+0

당신이 그 길로 가면 정말로해야 할 일이 많이 있습니다. 그래서 자동 생성 클래스를 직접 사용하지 않습니다. 이런 식으로 손을 굴려 보면 코드가 적고 코드가 적으며 디버깅이 쉬우 며 분리가 더 쉽습니다. –

+0

linq을 사용하여 저장 프로 시저를 추상화하고 기본적인 crud 작업을보다 쉽게 ​​수행 할 수 있습니다. 좋아요, 그 말이 많은 의미가 있습니다. 나는 코드 반복을 줄이는 데 사용할 수 있는지 알아보기 위해 제네릭을 살펴 보았습니다. – Aur