[.net] LINQ to Entities에서 메서드를 인식하지 못합니다.

linq 쿼리를 시도 할 때 다음 오류가 발생합니다.

LINQ to Entities는 ‘Boolean IsCharityMatching (System.String, System.String)’메서드를 인식하지 않으며이 메서드는 저장소 식으로 변환 할 수 없습니다.

나는 사람들이 동일한 오류를 얻는 이전 질문을 많이 읽었으며 이것을 올바르게 이해하면 LINQ to Entities에서 전체 linq 쿼리 식을 서버 쿼리로 변환해야하므로 외부 메서드를 호출 할 수 없기 때문입니다. 그것에. 내 시나리오를 아직 작동하는 것으로 전환 할 수 없었고 뇌가 녹기 시작했기 때문에 누군가가 나를 올바른 방향으로 안내 할 수 있기를 바랐습니다. 우리는 Entity Framework와 사양 패턴을 사용하고 있습니다.

사양을 사용하는 코드는 다음과 같습니다.

ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);

charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();

다음은 linq 표현식입니다.

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    return p => p.IsCharityMatching(this.charityName, this.charityReference);
}

IsCharityMatching 메서드는 다음과 같습니다.

public bool IsCharityMatching(string name, string referenceNumber)
{
    bool exists = true;

    if (!String.IsNullOrEmpty(name))
    {
        if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
            !this.alias.ToLower().Contains(name.ToLower()) &&
           !this.charityId.ToLower().Contains(name.ToLower()))
        {
            exists = false;
        }
    }

    if (!String.IsNullOrEmpty(referenceNumber))
    {
        if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
        {
            exists = false;
        }
    }

    return exists;
}

추가 정보가 필요하면 알려주세요.

감사합니다.

Annelie



답변

아시다시피 Entity Framework는 실제로 쿼리의 일부로 C # 코드를 실행할 수 없습니다. 쿼리를 실제 SQL 문으로 변환 할 수 있어야합니다. 이 작업을 수행하려면 쿼리 식을 Entity Framework가 처리 할 수있는 식으로 재구성해야합니다.

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    string name = this.charityName;
    string referenceNumber = this.referenceNumber;
    return p =>
        (string.IsNullOrEmpty(name) ||
            p.registeredName.ToLower().Contains(name.ToLower()) ||
            p.alias.ToLower().Contains(name.ToLower()) ||
            p.charityId.ToLower().Contains(name.ToLower())) &&
        (string.IsNullOrEmpty(referenceNumber) ||
            p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}


답변

이 코드에서 동일한 오류가 발생했습니다.

 var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

이것은 정확히 오류였습니다.

System.NotSupportedException : ‘LINQ to Entities는’Boolean Exists (System.Predicate`1 [conector_gp.Models.almacenes_por_sucursal]) ‘메서드를 인식하지 않으며이 메서드는 저장소 식으로 변환 할 수 없습니다.’

이 방법으로 해결했습니다.

var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

테이블 앞에 .ToList () 를 추가 하여 Entity와 linq 코드를 분리하고 다음 linq 표현식이 번역되지 않도록합니다.

참고 : 엔티티 필터링을 피하고 모든 테이블을 메모리에로드하기 때문에이 솔루션은 최적이 아닙니다.


답변

누군가가 VB.Net 답변을 찾고 있다면 (처음처럼) 여기에 있습니다.

Public Function IsSatisfied() As Expression(Of Func(Of Charity, String, String, Boolean))

Return Function(charity, name, referenceNumber) (String.IsNullOrWhiteSpace(name) Or
                                                         charity.registeredName.ToLower().Contains(name.ToLower()) Or
                                                         charity.alias.ToLower().Contains(name.ToLower()) Or
                                                         charity.charityId.ToLower().Contains(name.ToLower())) And
                                                    (String.IsNullOrEmpty(referenceNumber) Or
                                                     charity.charityReference.ToLower().Contains(referenceNumber.ToLower()))
End Function


답변

나는 당신과 비슷한 문제가 있었고이 LINQ 문서 는 제한 사항을 해결할 올바른 문자열 함수를 찾는 데 도움 되었습니다.


답변