code

지정된 형식 멤버는 LINQ to Entities에서 지원되지 않습니다.

codestyles 2020. 11. 24. 08:00
반응형

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


var result =
    (from bd in context.tblBasicDetails
     from pd in context.tblPersonalDetails.Where(x => x.UserId == bd.UserId).DefaultIfEmpty()
     from opd in context.tblOtherPersonalDetails.Where(x => x.UserId == bd.UserId).DefaultIfEmpty()
     select new clsProfileDate()
     {
         DOB = pd.DOB
     });

foreach (clsProfileDate prod in result)
{
    prod.dtDOB = !string.IsNullOrEmpty(prod.DOB) ? Convert.ToDateTime(prod.DOB) : DateTime.Today;
    int now = int.Parse(DateTime.Today.ToString("yyyyMMdd"));
    int dob = int.Parse(prod.dtDOB.ToString("yyyyMMdd"));
    string dif = (now - dob).ToString();
    string age = "0";
    if (dif.Length > 4)
    age = dif.Substring(0, dif.Length - 4);
    prod.Age = Convert.ToInt32(age);
}

GetFinalResult(result);

protected void GetFinalResult(IQueryable<clsProfileDate> result)
{
    int from;
    bool bfrom = Int32.TryParse(ddlAgeFrom.SelectedValue, out from);
    int to;
    bool bto = Int32.TryParse(ddlAgeTo.SelectedValue, out to);

    result = result.AsQueryable().Where(p => p.Age >= from);
}

여기에 예외가 있습니다.

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

Age가 데이터베이스에없는 경우 DOB에서 Age를 계산하기 위해 clsProfileDate 클래스에서 만든 속성입니다. 이것에 대한 해결책이 있습니까?


Where의 데이터베이스 열에 매핑되지 않은 속성은 사용할 수 없습니다 . 다음과 같이 매핑 된 속성을 기반으로 식을 작성해야합니다.

var date = DateTime.Now.AddYears(-from);
result = result.Where(p => date >= p.DOB);
// you don't need `AsQueryable()` here because result is an `IQueryable` anyway

매핑되지 않은 Age속성을 대체하기 위해 다음과 같이이 표현식을 정적 메서드로 추출 할 수 있습니다.

public class clsProfileDate
{
    // ...
    public DateTime DOB { get; set; } // property mapped to DB table column

    public static Expression<Func<clsProfileDate, bool>> IsOlderThan(int age)
    {
        var date = DateTime.Now.AddYears(-age);
        return p => date >= p.DOB;
    }
}

그런 다음 다음과 같이 사용하십시오.

result = result.Where(clsProfileDate.IsOlderThan(from));

A lot of people are going to say this is a bad answer because it is not best practice but you can also convert it to a List before your where.

result = result.ToList().Where(p => date >= p.DOB);

Slauma's answer is better, but this would work as well. This cost more because ToList() will execute the Query against the database and move the results into memory.


You will also get this error message when you accidentally forget to define a setter for a property. For example:

public class Building
{
    public string Description { get; }
}

var query = 
    from building in context.Buildings
    select new
    {
        Desc = building.Description
    };
int count = query.ToList();

The call to ToList will give the same error message. This one is a very subtle error and very hard to detect.


I forgot to select the column (or set/map the property to a column value):

IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
                                    where ...
                                    select new DataModel { Name = t.Name };

Calling queryable.OrderBy("Id") will throw exception, even though DataModel has property Id defined.

The correct query is:

IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
                                    where ...
                                    select new DataModel { Name = t.Name, Id = t.Id };

In this case, one of the easiest and best approach is to first cast it to list and then use where or select.

result = result.ToList().where(p => date >= p.DOB);

Checking Count() before the WHERE clause solved my problem. It is cheaper than ToList()

if (authUserList != null && _list.Count() > 0)
    _list = _list.Where(l => authUserList.Contains(l.CreateUserId));

참고URL : https://stackoverflow.com/questions/11584660/the-specified-type-member-is-not-supported-in-linq-to-entities-only-initializer

반응형