이니셜 라이저, 엔터티 멤버 및 엔터티 탐색 속성 만 지원됩니다.


102

이 예외가 발생합니다.

지정된 형식 멤버 '유료'는 LINQ to Entities에서 지원되지 않습니다. 이니셜 라이저, 엔터티 멤버 및 엔터티 탐색 속성 만 지원됩니다.

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .Where(o => o.Paid == false)
            .OrderByDescending(o => o.DateCreated);

        return View(debts);
    }

내 모델 클래스

public partial class Order
{
    public bool Paid {
        get {
            return TotalPaid >= Total;
        }
    }

    public decimal TotalPaid {
        get {
            return Payments.Sum(p => p.Amount);
        }
    }

결제는 금액 필드를 포함하는 관련 테이블입니다. 결제에 대한 올바른 정보를 보여주는 Where 절을 제거하면 쿼리가 작동합니다. 코드에 어떤 문제가 있는지 단서가 있습니까?

다음과 같이 제안 된 답변처럼 해결되었습니다.

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .OrderByDescending(o => o.DateCreated)
            .ToList()
            .Where(o => o.Paid == false);

        return View(debts);
    }

15
간단한 대답 : linq-to-entities 쿼리에서 매핑되지 않은 속성을 사용할 수 없습니다! 매핑 된 속성 만 SQL로 변환됩니다.
라디 Mrnka

답변:


114

엔터티가 유료 속성을 SQL로 변환하려고하는데 테이블 스키마의 일부가 아니기 때문에 할 수 없습니다.

할 수있는 일은 Entity가 유료 필터가없는 테이블을 쿼리 한 다음 유료 필터를 필터링하도록하는 것입니다.

public ActionResult Index()
{
    var debts = storeDB.Orders
        //.Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

    debts = debts.Where(o => o.Paid == false);

    return View(debts);
}

물론 이는 모든 데이터를 웹 서버로 다시 가져 와서 데이터를 필터링한다는 것을 의미합니다. DB 서버에서 필터링하려는 경우 테이블에 계산 된 열을 생성하거나 저장 프로 시저를 사용할 수 있습니다.


25

비슷한 문제를 해결해야했습니다. 위의 솔루션에는 메모리 내 처리가 필요하며 이는 나쁜 습관입니다 (지연로드).

내 해결책은 술어를 반환하는 도우미를 작성하는 것이 었습니다.

public static class Extensions
{
    public static Expression<Func<Order, bool>> IsPaid()
    {
        return order => order.Payments.Sum(p => p.Amount) >= order.Total;
    }
}

linq 문을 다음과 같이 다시 작성할 수 있습니다.

var debts = storeDB.Orders
                    .Where(Extensions.IsPaid())
                    .OrderByDescending(o => o.DateCreated);

이것은 계산 로직 (DRY)을 재사용하고자 할 때 편리합니다. 단점은 논리가 도메인 모델에 없다는 것입니다.


1
이 접근 방식을보다 "내장"하려는 많은 라이브러리가 있습니다. stackoverflow.com/a/27383641/470183을 참조하십시오 . Linq-to-entities는 SQL로 변환 될 수있는 "정규 함수"를 사용하는 표현식으로 제한됩니다. C # 6은 "표현 본문 함수"를 도입했지만 실제 람다가 아닙니다 (참조 : stackoverflow.com/a/28411444/470183 ). 그래도 WIBNI data.uservoice.com/forums/를
James Close

1
의 간단하고 간결한 예제에 감사드립니다 Expression<Func<xx,yy>>. 전에는 이해했지만 지금은 분명해 보입니다.
AlexB

17

이 문제는 또한 [NotMapped] DB 모델과 뷰 모델에서 이름이 같은 속성 .

AutoMapper는 프로젝션 중에 DB에서 선택하려고합니다. 그리고 NotMapped 속성은 분명히 DB에 존재하지 않습니다.

해결책은 IgnoreDB 모델에서 뷰 모델로 매핑 할 때 AutoMapper 구성의 속성에 있습니다.

  1. [NotMapped]이름이 있는 속성 찾기FooDB 모델에서 .
  2. 같은 이름의 속성을 찾으십시오. Foo보기 모델에서 .
  3. 이 경우 AutoMapper 구성을 변경하십시오. 더하다.ForMember(a => a.Foo, b => b.Ignore());

Dang AutoMapper Projection도 저를 잡았습니다. 답변 해 주셔서 감사합니다!
Chase Florell

15

Linq는 문을 SQL 문으로 변환하고 데이터베이스에서 실행합니다.

이제이 변환은 엔터티 멤버, 이니셜 라이저 및 엔터티 탐색 속성에 대해서만 발생합니다. 따라서 기능을 달성하거나 속성 비교를 얻으려면 먼저 메모리 내 목록으로 변환 한 다음 데이터를 검색하는 기능을 적용해야합니다.

따라서 전체적으로

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

21
나는 누군가에게 주문에 대해 toList ()를 만들도록 요청하는 것은 전체 목록을 검색하는 것을 의미하기 때문에 위험하다고
제안

내 문제 속성이 Where 절이 아닌 Sum Linq 함수에 있기 때문에 이것은 나에게 좋습니다. 그래서 나는 불필요한 데이터를 얻지 못하고 검색 된 데이터에 대해 List에서 작업하는 Linq Sum 기능을 수행하고 있습니다. 감사합니다! 처음에는 나빠 보일 수있는 것이 특정 상황에서 매우 도움이 될 수 있습니다!
Dov Miller

11

다른 가능한 이유는 IEnumerable 귀하의 자산에 하고 입니다.ICollection

그래서 대신 :

public class This
{
    public long Id { get; set; }
    //...
    public virtual IEnumerable<That> Thats { get; set; }
}

이 작업을 수행:

public class This
{
    public long Id { get; set; }
    //...
    public virtual ICollection<That> Thats { get; set; }
}

그리고 당신은 늠름한 도리 ... 2 시간을 잃는 것은 어리석은 일입니다.


2

이 상황은 unsigned int와 같이 EntityFramework 유형 에서 지원하지 않는 유형을 사용하는 경우에도 발생할 수 있습니다 .

이것은 그러한 오류의 경우였습니다.

지원되는 유형에 대한 추가 정보 확인 : https://msdn.microsoft.com/en-us/library/ee382832(v=vs.100).aspx

GFoley83 : Entity Framework에서 unsigned int / long 유형을 사용하는 방법에 설명 된 이러한 상황에 대한 몇 가지 해결 방법이 있습니다.


이 링크는 많은 시간을 절약했습니다! 정말 고마워!
Vladimir Semashkin

0

get without set속성 만있는 멤버 변수가 있기 때문에이 문제에 직면 했습니다.

그 자신의 수단 auto calculatednot stored열의로서the table

따라서 그 not exist안에table schema

따라서 a 및 속성 에 대한 make sure모든 멤버 변수not auto calculatedhavegettersetter


-1

edmx 및 컨텍스트 모델에는 db에 새로 추가되는 다른 속성이 있습니다.

EDMX를 업데이트하여 프로젝트를 올바르게 새로 고치고 다시 실행하십시오.

그것은 당신의 문제를 해결할 것입니다.

감사합니다, Ganesh Nikam

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