엔터티 프레임 워크 : LINQ to Entities는 캐스팅 엔터티 데이터 모델 기본 형식 만 지원합니다.

entity-framework primitive-types

문제

orderby 절에 대해 Expression을 전달할 수있는 메서드를 작성했지만이 문제가 발생했습니다.

'System.DateTime'형식을 'System.IComparable'형식으로 변환 할 수 없습니다. LINQ to Entities는 캐스팅 엔터티 데이터 모델 기본 형식 만 지원합니다.

기본적으로 표현은 다음과 같습니다.

Expression<Func<K, IComparable>> orderBy

그리고 이런 식으로 사용됩니다 :

SomeEntities.SomeTable
.Where
(
   whereClause
)
.Select
(
   selectClause
)
.OrderBy(orderBy)

아이디어는 다음과 같은 식으로 문자열 일치를 유지하기 위해 사전을 사용할 수 있도록하기위한 것입니다.

_possibleSortForForumItem.Add("CreateDate", item => item.CreateDate);

그런 다음 정렬 문자열을 받아서 사전의 키와 일치하는 식을 반환하는 메서드가 있습니다. 그렇지 않으면 일부 기본값이 반환됩니다. (아이디어는 순서에 따라 정렬 할 수있는 방법을 제어하는 방법입니다.) 이제는 String 속성에서 작동하지만, 위의 오류 메시지가 나타나면 datetime 또는 integer에 대해서는 그렇지 않습니다.

지금까지는 (느슨하게) Entity Framework가 C # DateTime을 데이터베이스에서 처리 할 수있는 것으로 변환해야하기 때문에 Entity Framework에서 기본 / EDM 형식이 필요하다는 것이 문제입니다.

datetime을 기본 유형으로 변환하여 여전히 작동 할 수있는 방법이 있습니까?

해결책

방법으로 주문을받는 방법 : (쿼리를 가져 와서 "주문 양식"으로 반환)

private static Func<IQueryable<ForumViewItem>, IOrderedQueryable<ForumViewItem>> GetMethodForSort(String sortBy)
{
  if (_methodForSort == null)
  {
    _methodForSort = new Dictionary<String, Func<IQueryable<ForumViewItem>, IOrderedQueryable<ForumViewItem>>>();
    _methodForSort.Add(SortForumViewItemCreatedOn, item => item.OrderBy(innerItem => innerItem.CreatedOn));
    ...
  }

  Func<IQueryable<ForumViewItem>, IOrderedQueryable<ForumViewItem>> orderMethod;

  if(String.IsNullOrEmpty(sortBy) || !_methodForSort.ContainsKey(sortBy))
  {
    orderMethod = _methodForSort["ForumName"];
  }
  else
  {
    orderMethod = _methodForSort[sortBy];
  }

  return orderMethod;
}

일반 쿼리 메서드의 메서드 시그니처 :

IList<K> GetListForGrid<T, K>(this ObjectQuery<T> query, ... Func<IQueryable<K>, IOrderedQueryable<K>> orderBy, ...)

그리고 전달 된 메서드의 사용 :

initialQuery = query
  .Where
  (
    somethingEqualsSomething
  )
  .Select
  (
    selectClause
  );

var orderedQuery = orderBy(initialQuery);

returnValue = orderedQuery
  .Skip(numberToShow * realPage)
  .Take(numberToShow)
  .ToList();

수락 된 답변

Entity Framework는이 작업을 어렵게 만들고 단일 반환 값 유형 (IComparable, object 등)을 사용하여 원하는 작업을 수행 할 방법이 있는지 확신하지 못합니다. 이름 대 Func<IQueryable<K>, IOrderedQueryable<K>> 값의 사전으로 디자인을 재 설계하는 것이 좋습니다.

_possibleSortForForumItem.Add("CreateDate", 
    query => query.OrderBy(item.CreateDate));

그런 다음 그것을 적용하십시오 :

var orderedQuery = query.OrderBy(item => item.DefaultOrderColumn);

Func<IQueryable<K>, IOrderedQueryable<K>> assignOrderBy = null;

if (_possibleSortForForumItem.TryGetValue(orderColumnName, out assignOrderBy))
{
    orderedQuery = assignOrderBy(query);
}

인기 답변

나는 이것이 오래된 것을 알고있다. 그러나 나는 OP와 똑같은 것을 성취하려고하고 있었고, Func<IQueryable<T>, IOrderedQueryable<T>> 을 사전에 사용하고 싶지 않았다. 주로 OrderByOrderByDescending 대리자를 모두 구현해야하기 때문입니다.

나는 ObjectSort 라는 IQueryable을위한 확장 메소드를 생성하는 것을 끝내었다. ObjectSort 는 단순히 표현식의 리턴 타입이 무엇인지를 확인한 다음 그 타입을 사용하여 새로운 람다를 생성하여 LINQ to Entities가 괴롭히지 않도록한다.

이것이 좋은 해결책인지 아닌지는 잘 모르겠지만, 아래의 예는 DateTimeint 작동합니다. 그렇게하면 비슷한 것을 성취하고자한다면 잘하면서 아이디어를 줄 수 있습니다!

public static IOrderedQueryable<T> ObjectSort<T>(this IQueryable<T> entities, Expression<Func<T, object>> expression, SortOrder order = SortOrder.Ascending)
{
    var unaryExpression = expression.Body as UnaryExpression;
    if (unaryExpression != null)
    {
        var propertyExpression = (MemberExpression)unaryExpression.Operand;
        var parameters = expression.Parameters;

        if (propertyExpression.Type == typeof(DateTime))
        {
            var newExpression = Expression.Lambda<Func<T, DateTime>>(propertyExpression, parameters);
            return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
        }

        if (propertyExpression.Type == typeof(int))
        {
            var newExpression = Expression.Lambda<Func<T, int>>(propertyExpression, parameters);
            return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
        }

        throw new NotSupportedException("Object type resolution not implemented for this type");
    }
    return entities.OrderBy(expression);
}


Related

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