2011-03-14 3 views
6

EF를 사용하고 있습니다.LINQ to EF에 무슨 문제가 있습니까?

List<Tuple<int, string>> lst = new List<Tuple<int, string>>(); 
var query= (from c in DALContext.MST 
      select new{c.CD, c.NAME}); 
foreach (var item in query) 
{ 
    lst.Add(new Tuple<int,string>(item.CD,item.NAME)); 
} 
return lst; 
: 만 매개 변수가없는 생성자와 초기화 내가이 쿼리를 다시 작성할 때

대신 엔티티에 LINQ에서 지원됩니다 :이

public List<Tuple<int, string>> GetList() 
{ 
    return (from c in DALContext.MST 
      select new Tuple<int, string>(c.CD, c.NAME)).ToList(); 
} 

는 i)는 GetList를 (호출이 예외가 발생하면 내 LINQ 쿼리입니다

잘 작동합니다. 내 첫 쿼리에 문제가 있습니까 ???

답변

11

다른 대답은 무슨 일이 일어나고 있는지에 대한 올바른,하지만 난 사람이 당신의 코드가 작동 할 수있는 가장 좋은 방법 언급 보지 못했다 : AsEnumerable()

public List<Tuple<int, string>> GetList() 
    { 
     return (from c in DALContext.MST.AsEnumerable() 
       select Tuple.Create(c.CD, c.NAME)).ToList(); 
    } 

AsEnumerable 방법이 있어야 할 코드 사이의 경계 역할을 SQL로 변환되어 데이터베이스 서버에서 실행되며, 데이터베이스에서 응답을 얻은 후 메모리에서 실행되어야하는 코드입니다. 테이블 이름 바로 뒤에 넣으면 EF에서 MST 테이블의 모든 레코드를 가져온 다음 반환되는 값에서 튜플을 만드는 다음 코드를 실행합니다.

귀하의 new Tuple<int, string>Tuple.Create으로 변경했습니다. 제네릭 유형 매개 변수를 입력하는 것이 더 이상 필요하지 않기 때문입니다.

+1

'AsEnumerable()'은'ToList()'또는'ToArray()'를 사용하는 것과는 다른 것입니까? – Despertar

+1

@Despertar - ToList()와 ToArray()는 목록이나 배열을 만들기 위해 질의 결과를 반복해야한다. 위의 예제에서'AsEnumerable()'을'ToList()'로 바꾸면 결과를 두 번 반복합니다. AsEnumerable()은 시퀀스를 소비하지 않기 때문에 한 번만 반복합니다. –

6

LINQ to EF는 LINQ to SQL과 약간 다른 쿼리를 처리합니다. EF에 LINQ에서, 당신은 코드의 첫 번째 비트에서 여기처럼 당신은 LINQ 표현에 매개 변수로 생성자를 넣을 수 없습니다

from c in DALContext.MST 
select new Tuple<int, string>(c.CD, c.NAME) 

튜플의 생성자는 두 개의 매개 변수를 취하고, 그 허용되지 않습니다 LINQ에서 EF로. 이 쿼리의 일부 서버 어떤에서 실행 것 사이의 경계에 대한 더 명시 적으로 엔티티에 LINQ를 원하는의 문제 부분에서

:

이유는 here를 설명 부분은 클라이언트에서 실행됩니다. SQL에 LINQ와

는, 예를 들어, 뿐만 아니라 서버의 서버 과 기능에서 데이터를 포함하지만 LINQ 쿼리를 작성하는 만 가능 클라이언트와에서 실행할 수 있습니다 또한 기능 에 함께 섞으십시오. 그러면 LINQ to SQL 공급자 은 항목을 풀고 서버에서 수있는 부분과 클라이언트에서 의 다른 부분을 실행할 수 있도록 최선을 다할 것입니다. 이것은 이 원하는 쿼리를 작성하기가 쉽기 때문에 을 원하고 가능하다면 이 작동합니다. 당신이 서버에서 실행할 수있는 유일한 부분은 하나 개 이상의 테이블에서 모든 데이터를 를 반환 가장 기본적인 것입니다 실수로 쿼리를 작성하고 모든 이있는 경우, 다른 한편으로는 하지 좋네요 필터링은 클라이언트에서 발생합니다 (매우 불쾌한 결과로).

LINQ to Entities의 경우 경계가 인 것이 더 명확합니다. 당신이 엔티티에 LINQ에 대해 된 IQueryable 구현을 LINQ 쿼리를 작성하는 경우, 전체 쿼리는 서버에서 실행하고 경우 쿼리의 일부가 은 다음 명시 적 경계를 만들어야합니다, 서버에서 실행할 수 없습니다 ToQueryable() 또는 ToList()와 같은 것입니다. 해당 쿼리가 실행 된 후 데이터를 검색 한 다음 LINQ to Objects를 사용하여 쿼리를 더욱 구체화 할 수 있습니다. 이렇게하면 경계가 정확히 어디에 있는지 알 수 있으므로 은 성능 문제를 추적하기가 쉽고 은 좋아합니다.관련된 제한 중 하나 인 은 LICQ 의 엔터티에있는 select 문에서 기본 생성자가 있고 매개 변수를 설정할 수있는 익명 형식 인 또는 다른 형식을 만들 수 있다는 것입니다. 이렇게하면 이라는 select 문에 부작용이 많이 생기는 것을 최소화 할 수 있습니다.

1

클래스는 EF에 Linq에 대한 매개 변수없는 생성자를 가질 필요가 당신은 다음과 같이 인스턴스화 할 수 있습니다

public List<Tuple<int, string>> GetList() 
{ 
    return (from c in DALContext.MST 
      select new Tuple<int, string>(){CD = c.CD, Name = c.NAME}).ToList(); 
} 

편집 : 당신은 위치에 있지 않은 경우

을 추가 매개 변수가없는 생성자를 TUPLE (이 경우 Tuple은 클래스 자체가 아닙니다.)에서 Linq를 EF로 선택하는 대신 2 단계 프로세스로 처리 할 수 ​​있습니다.

public List<Tuple<int, string>> GetList() 
{ 
    List<MST> mstList = (from c in DALContext.MST 
         select c).ToList(); 

    List<Tuple<int, string>> tupleList = new List<Tuple<int, string>>(); 

    mstList.foreach(c => tupleList.add(new Tuple(c.CD, c.Name))); 

    return tupleList; 
} 
+0

안타깝게도 중괄호는 속성 설정을위한 구문 설탕이므로 튜플에는 할당 할 수있는 CD 또는 이름 속성 (또는이 문제에 대해 할당 가능한 속성)이 없으므로 작동하지 않습니다. –

2

아니면 그냥

var query= (from c in DALContext.MST 
      select new{c.CD, c.NAME}).ToList().Select(x=>new Tuple(x.CD, x.NAME)); 

이 그것은 단지 DB에서 필요한 두 개의 열을 가져 오는 장점이있다을 작성할 수 있습니다.

+0

필요한 두 개의 열만 선택하는 것은 좋은 지적이지만, ToList를 두 번 호출하는 것보다 여전히 AsEnumerable 및 ToList를 선택합니다. –