2011-05-10 5 views
2

많은 열이있는 테이블이 있고 행의 모든 ​​문자열 필드를 함께 결합하여 검색 문자열을 각 필드와 차례로 비교하지 않고 검색 할 수 있습니다.linq를 사용하여 필드를 반복합니다.

명시 적으로 각 열 이름을 명시하지 않고 행을 반복하는 방법은 무엇입니까?

ColumnA | ColumnB | ... | ColumnN 
--------------------------------- 
    A | B | ... | N 

나는 결과 AB를 좀하고 싶습니다 ... N은

이것은 당신이 배열로 각 행이있는 경우 지금까지

string searchString = "text"; 
var searchCandidate = ATable.Where(... condition ...); // IQueryable<ATable> 
searchCandidate. // what goes here to loop through all fields ? 
+2

현재 가지고있는 코드를 제시해주십시오. 어떤 데이터 구조에 테이블이 있습니까? –

+0

나는 당신을 정확하게 이해했는지 알지 못하지만 질문에 몇 가지 정보를 추가했습니다. – Joe

+0

어떤 컨텍스트에서 'ATable'입니까? LINQ2SQL? EF? 'DataTable '? ...? –

답변

1

당신은 다음과 같이 식 트리를 구축하여 이러한 방법을 쓸 수 있습니다 Visual Studio에서 생성 된 DataContext에 대해 GetProperties로 변경할 수 있습니다.

이 필드를 string.Concat 문에 전달하는 식을 만들어야합니다. 후자가 문자열 배열을 받아들이면 NewArrayInit 표현식을 만들어 배열을 만듭니다.

다음으로 문자열을 함께 결합하는 Concat 메서드를 호출하고 string.Contains 메서드를 호출하여 문자열 리터럴이 우리가 만든 식에 있는지 여부를 테스트합니다.

다음은 방법의 AdventureWorks에서 실행하는 방법은 다음과 같습니다

void Main() 
{ 
    Addresses.Where (AnyColumnContains<Address> ("Seattle")).Dump(); 
} 

람다 번역 :

Addresses 
    .Where (
     entity => 
     String 
      .Concat (new String[] { entity.AddressLine1, entity.AddressLine2, 
            entity.City, entity.PostalCode }) 
      .Contains ("Seattle") 
    ) 

SQL 번역 :

-- Region Parameters 
DECLARE @p0 NVarChar(1000) = '%Seattle%' 
-- EndRegion 
SELECT [t0].[AddressID], [t0].[AddressLine1], [t0].[AddressLine2], [t0].[City], 
     [t0].[StateProvinceID], [t0].[PostalCode], [t0].[rowguid] AS [Rowguid], 
     [t0].[ModifiedDate] 
FROM [Person].[Address] AS [t0] 
WHERE ((([t0].[AddressLine1] + [t0].[AddressLine2]) + [t0].[City]) + [t0].[PostalCode]) 
     LIKE @p0 
+0

무엇 .... .... .... 난 그냥 줄거리를 잃었다. 소화 ... – Joe

+0

이것은 올바른 경로에 확실히있다, 나는 여전히 null 필드 및 문자열이 아닌 필드를 처리하는 방법을 알아야하지만 그것은 숙제이므로 표현식 트리를 사용하는 방법을 배울 수있다. 감사합니다 조! :) – Joe

1

당신은, Aggregate를 사용할 수있을 것입니다 열의 값 중. DataTable의 경우입니다.

+0

집계 함수를 사용하여 하나만 반복 할 수있었습니다 여러 행에 걸쳐 필드를 표시하여 한 열에 말하십시오. 한 행을 반복하는 방법은 무엇입니까? 또는 여러 필드가 연속적으로 나타 납니까? – Joe

+0

@ Joe : 귀하의 질문에 대한 제 의견에서 말했듯이, 각 행이 해당 값을 배열로 노출하는 경우에만 가능합니다. –

+0

귀하의 의견을 부탁드립니다, 그 경우에는 깡패 : P – Joe

1

이 시도 :

Expression<Func<T, bool>> AnyColumnContains<T> (string value) 
{ 
    var p = Expression.Parameter (typeof (T), "entity"); 

    var fieldAccessors = typeof (T) 
     .GetFields() 
     .Where (f => f.FieldType == typeof (string)) 
     .Select (f => Expression.Field (p, f)) 
     .ToArray(); 

    var fieldArray = Expression.NewArrayInit (typeof (string), fieldAccessors); 

    var concatCall = Expression.Call (typeof (string).GetMethod (
     "Concat", new[] { typeof (string[]) }), fieldArray); 

    var contains = Expression.Call (
     concatCall, 
     typeof (string).GetMethod ("Contains", new[] { typeof (string) }), 
     Expression.Constant (value)); 

    return Expression.Lambda<Func<T, bool>> (contains, p); 
} 

첫째, 우리는 개체 유형에서 모든 필드 (LINQPad이 필드를 사용하여 얻을 :

private void Form1_Load(object sender, EventArgs e) 
    { 
     DataTable dt = new DataTable(); 
     dt.Columns.Add(new DataColumn { DataType = typeof(int), ColumnName = "A" }); 
     dt.Columns.Add(new DataColumn { DataType = typeof(int), ColumnName = "b" }); 
     dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "c" }); 
     DataRow r; 
     for (int i=0;i<=5 ;i++) 
     { 
      r = dt.NewRow(); 
      r["A"] = i; 
      r["b"] = i + 2; 
      r["c"] = i.ToString(); 
      dt.Rows.Add(r); 

     } 
     var query = from DataRow row in dt.Rows.Cast<DataRow>().ToList() 
        let textUnion = GetFields(row) 
        select new { textUnion }; 
     dataGridView1.DataSource = query.ToList(); 

    } 
    string GetFields(DataRow row) 
    { 
     StringBuilder retValue=new StringBuilder(); 

     for (int i = 0; i < row.ItemArray.Length;i++) 
     { 
      retValue.Append(Convert.ToString(row[i])); 
     } 

     return retValue.ToString(); 
    } 
+0

흠 ... 문제는, 내 것은 datatable되지 않습니다. 그것은 System.Linq.IQueryable 유형입니다. – Joe

+0

@Joe, Iqueryable 선언을 표시 할 수 있습니까? – JTorrecilla

+0

어떻게 선언했는지 모르겠다. linqpad를 사용하고 있으며 내부적으로 객체를 생성한다. 난 그냥 linqtosql 테이블을 사용 – Joe

관련 문제