2012-08-27 3 views
1

3-Tier 응용 프로그램을 작성 중입니다. 또한 데이터 액세스를 위해 SQL에 LINQ를 사용하고 있습니다.LINQ 조인 메서드의 올바른 반환 값은 무엇입니까?

public IEnumerable<Customer> getCustomers() 
{ 
    CustomerDAL customerDAL = new CustomerDAL(); 

    return from c in customerDAL.getCustomers() select c;    
} 
:

public Table<Customer> getCustomers() 
{ 
    DataContext context = new DataContext(); 
    Table<Customer> customerTable = context.GetTable<Customer>(); 

    return customerTable; 
} 

그것은 결과가 IEnumerable<Customer>로 프리젠 테이션 레이어에 전달되고있는 비즈니스 계층에 제공됩니다

데이터 영역은 고객의 테이블을 반환하는 기능을 가지고있다

Presentation-Layer에서 나는 단순히 DatagridView의 DataSource에 IEnumerable을 사용하고 있습니다.

"정보"와 customerDAL.getInfo() 테이블에 따라 다른 테이블이 있다면 어떨까요? 이제 Business-Layer의 메소드에서 조인 조회를 작성하려고합니다.

public IEnumerable<Customer> getCustomerInfo() 
{ 
    CustomerDAL customerDAL = new CustomerDAL(); 

    return from c in customerDAL.getCustomers() 
        join i in customerDAL.getInfo() on c.id equals i.InfoID 
        select new { c.id, c.Name, i.DateTime, i.Project }; 
} 

문제는 IEnumerable을 객체의 유형을 필요가있다 : 나는이 같은 상상. 내 반환 값은 더 이상 고객 테이블이 아니라 고객 및 정보 테이블의 조합입니다. 나는 그것을 올바르게 받았 느냐? 여기서 반환 값에 대한 올바른 선택은 무엇입니까? 리드에 의해 설명 된 바와 같이

public class CustomerInfo 
    {   
     string name { get; set; } 
     long id { get; set; } 
     string dateTime { get; set; } 
     string project { get; set; } 


     public CustomerInfo(long _id, string _name, string _date, string _project) 
     { 
      name = _name; 
      id = _id; 
      dateTime = _date; 
      project = _project; 
     } 
    } 

가 그럼 난 똑같은 메소드를 호출하고 있습니다 :

조언 후에 나는 사용자 정의 클래스, CustomerInfo.cs를 만들었습니다.

The query contains references to items defined on a different data context. 

는 사실이 모든 엔티티 클래스가 동일하면 .dbml 파일에있는 사실이 아니다 :하지만이 데이터 소스를 설정 프리젠 테이션 레이어에서 나는 예외를 얻을. 무엇이 잘못 될 수 있습니까?

답변

1

: 리드에 의해 설명 된 바와 같이

가 그럼 난 똑같은 메소드를 호출하고

. 그러나 Presentation-Layer에서 DataSource를 설정할 때 예외가 발생합니다. 쿼리에 다른 데이터 컨텍스트에 정의 된 항목에 대한 참조가 포함되어 있습니다.

아마도 DAL은 반환 할 각 테이블 (ActiveRecord 패턴 구현에서 일반)에 대한 컨텍스트의 별도 인스턴스를 인스턴스화하고 있습니다. 조인이 작동하려면 두 테이블을 동일한 컨텍스트 개체에서 검색해야합니다. 컨텍스트의 수명을 중앙 집중화 할 수 있도록 DAL의 생성자에 컨텍스트를 삽입 할 수 있도록 DAL을 수정해야 할 수 있습니다.

0

지금까지 모든 것이 훌륭하게 보입니다. 단일 메서드의 범위 내에서 쿼리를 사용하려면 익명 클래스 (현재 수행중인 작업)를 사용하는 것이 좋습니다. 그렇지 않으므로 반환 할 수 있도록 투영에 대한 구체적인 클래스를 만들어야합니다.

쿼리가 될 것입니다 :

select new SomeClassYouAreAboutToCreate { c.id, c.Name, i.DateTime, i.Project }; 

그 클래스는 아마 등의 특성, id, Name, 당신은 단지 Select에서 이러한 속성을 설정합니다 잔뜩 할 수 있습니다.

+0

IEnumerables로 채워진 사용자 지정 클래스에서 LINQ 쿼리를 실행하고 반환 값을 데이터 소스로 사용할 수 있습니까? – Prot

1

What would be the right choice for a return value here?

는 강력한 형식의 클래스를 반환 할 경우, 이러한 CustomerInfo 클래스로,이 유형을 표현하기 위해 사용자 정의 클래스가 필요합니다. 이 클래스를 정의하고 적절한 속성 및 생성자를 포함해야합니다. 그러면 다음 작업을 수행 할 수 있습니다.

이렇게하면 강하게 입력 된 방식으로 필요한 정확한 정보를 반환 할 수 있습니다. 이 경우 사용자 정의 클래스를 작성하는 것이 공개 API의 일부로 정의되어 있으므로이 경우 특히 중요하다고 주장합니다.

+0

IEnumerables로 채워진 사용자 정의 클래스에서 LINQ 쿼리를 실행하고 반환 값을 DataSource로 사용할 수 있습니까? – Prot

+0

@Prot 아니요 - LINQ to Objects를 사용하여 결과를 필터링 할 수는 있지만 더 이상 DB에 대해 작동하지 않는 DataSource는 아닙니다. –

0

그런 익명 개체를 만들 때 해당 형식은 dynamic입니다.dynamic 유형 단점을 가지고,

public IEnumerable<dynamic> getCustomerInfo() { 
    CustomerDAL customerDAL = new CustomerDAL(); 

    return from c in customerDAL.getCustomers() 
     join i in customerDAL.getInfo() on c.id equals i.InfoID 
     select new { c.id, c.Name, i.DateTime, i.Project }; 
} 

는하지만, 유의 사항 : 그래서 같은 익명 개체의 목록을 반환하려면 다음 서명을 사용합니다. 특히, 어려운 타이핑을 놓치면 찾기 힘든 버그가 생길 수 있습니다. 보다 견고한 솔루션을 위해서는 Servy's answer을 고려해야합니다. 두 번째 오류에 관한

+0

dype이 동적이 아닙니다. 그것은 강력하게 입력 된 익명입니다. – usr