2009-05-19 5 views
3

우선, 제목이 맞지 않을 경우를 대비하여 사과 드리겠습니다. 나는 내가하고있는 일을 설명하는 데 적합한 단어를 사용할 수는 없지만, 내가하고있는 일을 이해하는 데 어려움을 겪고있다.Func 목록으로 IQueryable에서 .Select() 수행

내가 헤더/LINQ 표현 조합에 의해 열을 정의하는 일반적인 그리드 클래스를 짓고 있어요 :

public class Column<T> 
{ 
    public string Header { get; set; } 
    public Func<T, string> ValueExpression { get; set; } 
} 

사용법 :

Columns = new List<Column<Employee>> 
       { 
        new Column<Employee> {Header = "Employee Id", ValueExpression = e => e.EmployeeID.ToString()}, 
        new Column<Employee> {Header = "Name", ValueExpression = e => e.FirstName + " " + e.LastName}, 
        new Column<Employee> {Header = "Employee Birthday Year", ValueExpression = e => e.BirthDate.HasValue ? e.BirthDate.Value.Year.ToString() : ""} 
       }, 

내가 투사 할 ValueExpression의 (Func<T, string>)를 IQueryable 'employees'에 추가하십시오.

var db = new NorthwindDataContext(); 
var employees = db.Employees.Select(e => e); 

)합니다 (PagedList 물건을 신경 쓰지 마

var elementsList = employees.ToPagedList(PageIndex, PageSize); 
var elementStringList = elementsList.ToStringList(Columns.Select(c => c.ValueExpression).ToArray()); 

, 그것은 무관와 ToList 등 좀 동일합니다; 직원에서이 같은 (내보기에 사용되는 문자열 목록의 목록을)를 IEnumerable<IEnumerable<string>>를 추출하는 동안 작업을

여기에 ToStringList() 메소드의 확장 :

public static IEnumerable<IEnumerable<string>> ToStringList<T>(this IPagedList<T> enumerable, params Func<T, string>[] fields) 
{ 
    foreach (var element in enumerable) 
     yield return element.ToStringList(fields); 
} 

private static IEnumerable<string> ToStringList<T>(this T element, params Func<T, string>[] fields) 
{ 
    foreach (var field in fields) 
     yield return field(element); 
} 

문제는이 방법이 리턴되어야하는 필드를 지정하기 전에 실행 된 IQueryable을 포함한다는 것이다. 그 결과

은, 다음 쿼리는 어딘가에 길을 따라 실행됩니다 : 당신이 알 수 있듯이,이 테이블 종업원의 모든 필드를 검색하기 위해 바람직하지

SELECT [t0].[EmployeeID], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0].[TitleOfCourtesy], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[HomePhone], [t0].[Extension], [t0].[Photo], [t0].[Notes], [t0].[ReportsTo], [t0].[PhotoPath] 
FROM [dbo].[Employees] AS [t0] 

.

필자는 List of Func (Column의 "ValueExpression"멤버)을 전달하고 새로운 IQuerable을 "빌드"할 수있는 IQueryable 직원들에게 확장 메소드를 구축하는 방법을 찾고 있습니다. 데이터베이스에서 필요한 필드를 검색하는 SQL을 실행합니다.

그래서 나는 이런 식으로 뭔가를 찾고 있어요 : 사전에

IQueryable employees = employees.SelectByExpressions(Columns.Select(c => c.ValueExpression).ToArray()); 

감사합니다.

답변

0

...

+0

감사합니다. 들어 본 적이 없습니다. 해당 페이지에 많은 샘플 코드가 있으므로 필요한 정보를 찾을 수 있습니다. 오늘 저녁에 확인해 볼께. –

+0

나는 Predicate Builder가 당신이 원하는 것을 할 것이라고 생각지 않는다. Select 문을 동적으로 작성하려고 할 때 동적으로 술어 (Where 절)를 동적으로 작성하는 것입니다. –

0

Dynamic Linq에 대해 살펴 보았습니까? 나는 네가하려는 일을한다고 믿는다.

열이 문자열 인 경우이 속성을 사용하여 select 술어를 수행 할 수 있으며 SQL에 실행되는 열만 포함됩니다.

+0

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx –

+1

동적 인 Linq가 작동하지 않습니다. 그것은 술어와 순서 절에 문자열 표현식을 사용합니다. 그러나 아래에서 설명 하듯이 궁극적 인 결과는 구체적 유형이어야하기 때문에 Select 문에서 사용할 수 없습니다. –

1

실행해야 할 기본적인 문제는 Select가 일부 유형의 객체를 반환해야하지만 생성 된 동적 쿼리에 따라 유형이 다른 필드를 갖기를 원합니다. 익명 형식을 사용하면 컴파일러에서 적절한 필드가있는 형식을 생성합니다. 그러나 귀하의 경우에는 컴파일시에 필드 목록이 어떻게 보이는지 알지 못하므로 컴파일러에서 유형을 생성 할 수 없습니다.

원하는 필드 만 포함하는 유형을 동적으로 빌드하는 것이 가능하지만이 작업이 필요한지 여부를 중단하고 질문해야합니다. LINQ-to-SQL과 같은 O/R 맵퍼를 사용하는 것의 정당성 중 일부는 DataSet과는 달리 다른 시간대에 다른 필드 집합을 동적으로 반환하는 코드를 유지 관리하는 데 드는 비용이 쿼리에서 얻은 소액의 절약에 가치가 없다는 것입니다. 또는 메모리 사용량. 실제로 어떤 경우에는 데이터베이스 서버가 동일한 필드 목록으로 여러 쿼리를 최적화 할 수있는 것과 같은 방법으로 다른 필드 목록을 사용하여 여러 쿼리를 최적화 할 수 없기 때문에 쿼리 성능이 저하 될 수도 있습니다.

또 다른 옵션은 항상 모든 필드를 반환하지만 선택된 필드 만 표시하는 것입니다. 그것은 확실히 더 간단하고 유지하기가 훨씬 쉬울 것입니다. 그러나 해당 솔루션의 성능 영향을 측정하여 요구 사항을 충족시키지 못한다고 판단한 경우 필요한 유형을 동적으로 생성 할 수 있습니다. 해당 솔루션에 대한 도움이 필요하면 샘플을 준비 할 수 있습니다. 그러나 내가 너라면, 나는 그 길을 시작하기 전에 그 길을 갈 필요가 있다는 것을 절대 확신 할 수있을 것이다.

업데이트 : 다른 질문은이 쿼리를 사용하여 목표를 그리드에 표시할지 아니면 다른 종류의 동적으로 바인딩 된 인터페이스로 표시할지 여부입니다. 그렇다면 관련된 특정 필드가있는 구체적인 유형은 없지만 키/값 쌍을 담는 컨테이너 인 DataRow와 비슷한 일종의 "속성 백"솔루션을 사용하는 것이 쉽습니다. . 그러나 코드에서 조작 할 수있는 형식을 동적으로 만들려는 경우 해당 형식을 강력히 권장합니다. 기술적 인 구현은 흥미로울 수 있지만 유지 보수는 매우 빠르게 악몽이됩니다. 나는 전에 그런 응용 프로그램을 유지하도록 강요 당했고, 내가 선택의 여지가 있다면 나는 결코 다시는 존재하지 않을 것입니다.

+0

매우 흥미로운 대답에 감사드립니다. 특히 다른 필드 목록으로 쿼리를 최적화 할 수없는 DB 서버에 관한 부분은 좋은 지적입니다. 아직 성능을 측정하지는 않았지만 그 점에 대해 알아 보겠습니다. 어느 쪽이든, 동적 유형 생성을 사용하여 여러 가지 유형의 테이블과 쿼리 (많은 열, 많은 행 ...)의 성능을 비교할 수있는 솔루션을 갖고 싶습니다. 그 이유와 교육적 목적을 위해 올바른 방향으로 나를 얻기 위해 표본을 요리 할 의향이 있다면 고맙겠습니다. –

관련 문제