LINQ에서 엔티티 : 분할 방법을 조건으로 사용할 수없는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1354723

문제

다음 LINQ 쿼리가 있습니다.

var aKeyword = "ACT";
var results = from a in db.Activities
              where a.Keywords.Split(',').Contains(aKeyword) == true
              select a;

키워드는 쉼표로 구분 된 필드입니다.

이 쿼리를 실행할 때마다 다음 오류가 발생합니다.

"LINQ to Entities 'Boolean은 [string] (System.Collections.generic.ienumerable`1 [System.String], System.String)를 포함하는 방법을 인식하지 못하며이 메소드는 저장 표현식으로 변환 될 수 없습니다."

내가하려는 일의 대안은 무엇입니까?

도움이 되었습니까?

해결책

큰 데이터 세트에서의 성능 고려 사항에 대한 응답으로 :

클라이언트에서 인덱싱되지 않은 와일드 카드 문자열을 일치시킬 것이므로 성능 손실이있을 것입니다.

한 테이블 필드에 여러 키워드가있는 이유가 있습니까? 각 활동마다 여러 키워드 레코드가있는 ActivityKeywords 테이블을 갖도록 정규화 할 수 있습니다.

Activity (Activity_ID, ... / * 키워드 제거 필드 * /) ---> ActivityKeywords (activity_id, keyword_id) ---> 키워드 (keyword_id, value)

첫 번째가 아닌 정상 양식을 확인하십시오. http://en.wikipedia.org/wiki/database_normalization

편집 : 또한 하나의 열을 고수하더라도 서버 사이드를 모두 수행 할 수있는 방법이 있습니다 (엄격한 구문이있는 경우 'keyword1, keyword2, ..., keywordn') :

var aKeyword = "ACT";
var results = (from a in db.Activities
              where a.Keywords.Contains("," + aKeyword) || a.Keywords.Contains(aKeyword + ",")
              select a;

다른 팁

문제는 LINQ-to-Entites가 데이터베이스로 전송하기 위해 제공하는 모든 것을 SQL로 변환해야한다는 것입니다.

그것이 실제로해야 할 일이라면 LINQ-to-Entities가 모든 데이터와 LINQ-to-Objects를 철회하여 조건을 평가해야합니다.

전:

var aKeyword = "ACT";
var results = from a in db.Activities.ToList()
              where a.Keywords.Split(',').Contains(aKeyword) == true
              select a;

그러나 이것은 활동 테이블에서 모든 객체를 뒤로 당길 것임을 알아야합니다. 대안은 DB가 약간의 초기 필터를 수행하고 나중에 나머지 길을 필터링하는 것입니다.

var aKeyword = "ACT";
var results = (from a in db.Activities
              where a.Keywords.Contains(aKeyword)
              select a).ToList().Where(a => a.KeyWords.Split(',').Contains(aKeyword));

Linq-to-Entities가 이해하는 필터 (string.crantains는 쿼리가됩니다) 일부 데이터를 필터링 한 다음 객체를 다시 가져 오면 LINQ-to-Objects를 통해 원하는 실제 필터를 적용 할 수 있습니다. . Tolist ()는 LINQ-to-Entities를 강제로 쿼리를 실행하고 개체를 빌드하여 LINQ-to-Objects가 쿼리의 두 번째 부분을 수행하는 엔진이 될 수 있도록합니다.

내 생각에 당신이 분할을 부르는 방식입니다. 배열이 필요합니다. 아마도 LINQ에 또 다른 분할이있을 수 있습니다.

이것은 LINQ에서 개체에 대해 작동합니다.

 var dataStore = new List<string>
                    {
                        "foo,bar,zoo",
                        "yelp,foo",
                        "fred",
                        ""
                    };
 var results = from a in dataStore
               where a.Split(new[] {','}).Contains("foo")
               select a;

 foreach (var result in results)
 {
     Console.WriteLine("Match: {0}", result);
 }

다음을 출력합니다.

Match: foo,bar,zoo
Match: yelp,foo

사실, 그것에 대해 생각하면 분할이 필요합니까? a.Contains("foo") 당신을 위해 충분할 수 있습니다 (당신이 타격하고 싶지 않다면 foobar).

당신은 원할 수도 있습니다 L2E 및 .crantains에 대한이 질문을보십시오 클라이언트 쪽을 필터링하기 전에 슈퍼 세트에서 추측하는 것보다 더 효율적이어야하는 솔루션의 경우.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top