이 유형에서는 상수 유형의 상수 값을 작성할 수 없음 기본 유형 또는 열거 유형 만 지원됩니다.


164

아래 쿼리에 대해이 오류가 발생합니다.

유형의 상수 값을 만들 수 없습니다 API.Models.PersonProtocol. 이 컨텍스트에서는 기본 유형 또는 열거 유형 만 지원됩니다.

ppCombined아래이다 IEnumerable의 오브젝트 PersonProtocolType2 개 CONCAT 의해 구성되고, PersonProtocol목록.

왜 이것이 실패합니까? 우리는 LINQ를 사용할 수 없습니다 JOIN절 내부의 SELECT(A)의 JOIN?

var persons = db.Favorites
    .Where(x => x.userId == userId)
    .Join(db.Person, x => x.personId, y => y.personId, (x, y) =>
        new PersonDTO
        {
            personId = y.personId,
            addressId = y.addressId,                   
            favoriteId = x.favoriteId,
            personProtocol = (ICollection<PersonProtocol>) ppCombined
                .Where(a => a.personId == x.personId)
                .Select( b => new PersonProtocol()
                 {
                     personProtocolId = b.personProtocolId,
                     activateDt = b.activateDt,
                     personId = b.personId
                 })
        });


답변:


232

ppCombined메모리에있는 오브젝트의 콜렉션 이므로 데이터베이스에있는 데이터 세트를 메모리에있는 다른 데이터 세트와 결합 할 수 없으므로 작동하지 않습니다. 대신 데이터베이스에서 다른 속성을 검색 한 후 메모리 personProtocol에서 ppCombined컬렉션 의 필터링 된 항목을 추출 할 수 있습니다 .

var persons = db.Favorites
    .Where(f => f.userId == userId)
    .Join(db.Person, f => f.personId, p => p.personId, (f, p) =>
        new // anonymous object
        {
            personId = p.personId,
            addressId = p.addressId,   
            favoriteId = f.favoriteId,
        })
    .AsEnumerable() // database query ends here, the rest is a query in memory
    .Select(x =>
        new PersonDTO
        {
            personId = x.personId,
            addressId = x.addressId,   
            favoriteId = x.favoriteId,
            personProtocol = ppCombined
                .Where(p => p.personId == x.personId)
                .Select(p => new PersonProtocol
                {
                    personProtocolId = p.personProtocolId,
                    activateDt = p.activateDt,
                    personId = p.personId
                })
                .ToList()
        });

10
나를 위해 중요한 부분은 나머지 메모리에서 쿼리이며, 여기 .AsEnumerable () // 데이터베이스 쿼리 끝을 추가했다
사미르 Alibhai

2
@Slauma 성능에 관심이 있다면 모든 데이터를 메모리에 먼저로드 한 다음 쿼리 하므로이 작업을 피해야합니다. 이 시나리오에 대해 원시 SQL을 작성해야합니까?
Arvand

@Arvand가 좋은 점이있는 것 같습니다. 필터 이전에 많은 수의 레코드가있는 경우 사용 가능한 메모리 리소스에서 많은 시간이 소요될 수 있습니다.
spadelives

5
@Slauma "ppCombined는 메모리에있는 객체의 모음이므로 데이터베이스에있는 데이터 세트를 메모리에있는 다른 데이터 세트와 결합 할 수 없기 때문에 작동하지 않습니다." 이와 같은 것에 대한 문서는 어디서 찾을 수 있습니까? 나는 EF의 한계에 대한 지식이 부족하고, 이와 같은 쿼리 결과 세트를 제한하려고 할 때,이 무능함은 그 자체를 매우 명백하게하고 속도를 늦춘다.
Nomenator

1
좋은 정보입니다. 가장 직관적 인 예외 메시지 목록에이 예외를 추가하고 있습니다. 왜 발생하는지 이해 한 후에 만 ​​의미가 있습니다.
DVK

2

누군가 이것을 검색하는지 모릅니다. 나는 같은 문제가 있었다. 쿼리를 선택한 다음 where (또는 join)를 수행하고 select 변수를 사용하면 문제가 해결되었습니다. (문제는 "Reintegraties"컬렉션에있었습니다.)

query.Select(zv => new
            {
                zv,
                rId = zv.this.Reintegraties.FirstOrDefault().Id
            })
            .Where(x => !db.Taken.Any(t => t.HoortBijEntiteitId == x.rId
                                             && t.HoortBijEntiteitType == EntiteitType.Reintegratie
                                             && t.Type == TaakType))
            .Select(x => x.zv);

이것이 누군가를 돕기를 바랍니다.


6
zv.this.Reintegraties.FirstOrDefault().Id잠재적 NullReferenceException

2

필자의 경우 다음을 수행하여 문제를 해결할 수있었습니다.

내 코드를 다음과 같이 변경했습니다.

var r2 = db.Instances.Where(x => x.Player1 == inputViewModel.InstanceList.FirstOrDefault().Player2 && x.Player2 == inputViewModel.InstanceList.FirstOrDefault().Player1).ToList();

이에:

var p1 = inputViewModel.InstanceList.FirstOrDefault().Player1;
var p2 = inputViewModel.InstanceList.FirstOrDefault().Player2;
var r1 = db.Instances.Where(x => x.Player1 == p1 && x.Player2 == p2).ToList();

이것은 나를 위해 작동하지 않습니다. 따라 p1p2메모리에 모두 그들은 익명으로 선언하거나 변수의 이름으로되어 있는지.
Rahat Zaman

2
변수 유형은 문제가되지 않습니다. 필자의 경우 Where 절에서 .FirstOrDefault ()를 수행했기 때문에 오류가 발생했습니다.
콜린

2

OP의 코드 샘플은 달리 입증 할 수있는 충분한 컨텍스트를 제공하지 않기 때문에 추가 할 가치가 있지만 다음 코드 에서도이 오류가 발생했습니다.

public RetailSale GetByRefersToRetailSaleId(Int32 refersToRetailSaleId)
{
    return GetQueryable()
        .FirstOrDefault(x => x.RefersToRetailSaleId.Equals(refersToRetailSaleId));
}

분명히 사용할 수 없습니다 Int32.Equals 이 맥락에서 Int32를 원시 int와 비교하는 데 . 나는 이것을 (안전하게) 바꿔야했다.

public RetailSale GetByRefersToRetailSaleId(Int32 refersToRetailSaleId)
{
    return GetQueryable()
      .FirstOrDefault(x => x.RefersToRetailSaleId == refersToRetailSaleId);
}

EF는 Equals완벽하게 받아 들입니다.
Gert Arnold

0

AsEnumerable ()과 ToList ()를 추가하면 다음과 같습니다.

db.Favorites
    .Where(x => x.userId == userId)
    .Join(db.Person, x => x.personId, y => y.personId, (x, y).ToList().AsEnumerable()

ToList().AsEnumerable()

0

나는이 문제를 겪었고 문제를 해결 하고 해결AsEnumerable()것은 Join 절 바로 전에 사용했다는 것 입니다. 내 쿼리는 다음과 같습니다.

List<AccountViewModel> selectedAccounts;

 using (ctx = SmallContext.GetInstance()) {
                var data = ctx.Transactions.
                    Include(x => x.Source).
                    Include(x => x.Relation).
                    AsEnumerable().
                    Join(selectedAccounts, x => x.Source.Id, y => y.Id, (x, y) => x).
                    GroupBy(x => new { Id = x.Relation.Id, Name = x.Relation.Name }).
                    ToList();
            }

이 문제가 발생하는 이유가 궁금해졌으며 이제는 LINQ 를 통해 쿼리 한 후 결과가 메모리에 있고 객체에로드 되지 않기 때문에 그 상태가 무엇인지 모르지만 일부는 과도기 상태 라고 생각합니다. 그런 다음 AsEnumerable()또는 ToList()등 을 사용 하면 실제 메모리 객체에 배치하고 문제가 해결됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.