이 LINQ join statement가 작동하지 않는 이유는 무엇입니까?

c# entity-framework join linq linq-to-entities

문제

나는이 LINQ-query를 가지고있다 :

    // types...
    LinkedList<WeightedItem> itemScores = new LinkedList<WeightedItem>();

    var result = from i in _ctx.Items
                 join s in itemScores on i.Id equals s._id
                 orderby s._score descending
                 select new ItemSearchResult(i, s._score);

    // this fails:
    return result.ToList();

이 오류를 생성하는 것은 :

'System.Collections.Generic.IEnumerable`1 유형의 상수 값을 만들 수 없습니다.
이 컨텍스트에서는 원시 형식 ( 'Int32, String 및 Guid'와 같은) 만 지원됩니다.

[편집] 다음은 WeightedItem 의 코드입니다.

public class WeightedItem
{
    public int _id;
    public decimal? _score;

    public WeightedItem(int id, decimal? score)
    {
        _id = id;
        _score = score;
    }
}

내가 잘못한 것을 볼 수 있니? 코드가 완벽하게 컴파일되고 _ctx.Items 및 itemScores가 모두 적절한 값을 포함합니다.

수락 된 답변

예, 괜찮습니다. 문제는 SQL로 변환 할 수 없다는 것입니다. "로컬"값을 참조 할 때 엔티티 프레임 워크는 SQL 쿼리를 만들어야 할 때이를 처리해야합니다. 기본적으로 메모리 내 모음과 데이터베이스 테이블 간의 조인을 처리 할 수 없습니다.

사용할 있는 한 가지 방법은 대신 Contains 를 사용하는 것입니다. LinkedList<T> 가이 작업을 수행 할지는 모르지만 적어도 LINQ to SQL에서는 List<T> 가 사용한다고 생각합니다.

List<int> requiredScoreIds = itemScores.Select(x => x._id).ToList();

var tmp = (from i in _ctx.Items
           where requiredScoreIds.Contains(i.Id)
           orderby s._score descending
           select i).AsEnumerable();

// Now do the join in memory to get the score
var result = from i in tmp
             join s in itemScores on i.Id equals s._id
             select new ItemSearchResult(i, s._score);

이제는 메모리 내 쿼리에서 조인을하고 있는데, 이는 다소 불필요합니다. 대신 사전을 사용할 수 있습니다.

List<int> requiredScoreIds = itemScores.Select(x => x._id).ToList();

var tmp = (from i in _ctx.Items
           where requiredScoreIds.Contains(i.Id)
           orderby s._score descending
           select i).AsEnumerable();

// Create a map from score ID to actual score
Dictionary<int, decimal?> map = itemScores.ToDictionary(x => x._id,
                                                        x => x._score);

var result = tmp.Select(i => new ItemSearchResult(i, map[i.Id]));

인기 답변

메모리 목록과 쿼리 할 수있는 개체 사이에 조인 할 수 없습니다. 다음과 같이해야합니다.

var criteria = itemScores.Select(x => x._id).ToList();
var result_tag = (from i in _ctx.Items
                 where criteria.Contains(i.ID)
                 select i).ToList();
var result = from i in result_tag
             join s in itemScores on i.ID equals s._id
             orderby s._score descending
             select new ItemSearchResult(i, s._score);


Related

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.