Escribí un método para permitir que se pasara una expresión para la cláusula orderby, pero me encontré con este problema.Entity Framework: LINQ to Entities only supports casting Entity Data Model tipos primitivos
No se puede convertir el tipo 'System.DateTime' para escribir 'System.IComparable'. LINQ a Entidades solo admite el fundido de Datos de entidad Tipos primitivos de modelo.
Básicamente la expresión es la siguiente:
Expression<Func<K, IComparable>> orderBy
y se utiliza de esta manera:
SomeEntities.SomeTable
.Where
(
whereClause
)
.Select
(
selectClause
)
.OrderBy(orderBy)
La idea es para que pueda utilizar un diccionario para sostener cadena coincide con expresiones como:
_possibleSortForForumItem.Add("CreateDate", item => item.CreateDate);
Luego tengo un método que toma en la cadena de ordenamiento y devuelve la expresión si coincide con una clave en el diccionario, si no devuelve algún valor predeterminado. (La idea es una forma de controlar por lo que se puede ordenar) Ahora esto funciona para las propiedades de cadena, pero hasta ahora no para fecha o entero ya que recibo el mensaje de error anterior.
Ahora que yo (vagamente) entiendo el problema es que Entity Framework necesita que sea un tipo Principal/EDM porque tiene que convertir el C# DateTime en algo que la base de datos puede manejar.
¿Hay alguna manera de convertir el datetime a un tipo primitivo para que esto funcione?
Solución
El método para conseguir la orden por el método: (Tome en una consulta y devolverlo en "forma ordenada")
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;
}
La firma del método para el método de consulta genérica:
IList<K> GetListForGrid<T, K>(this ObjectQuery<T> query, ... Func<IQueryable<K>, IOrderedQueryable<K>> orderBy, ...)
Y el uso del pasado en el método:
initialQuery = query
.Where
(
somethingEqualsSomething
)
.Select
(
selectClause
);
var orderedQuery = orderBy(initialQuery);
returnValue = orderedQuery
.Skip(numberToShow * realPage)
.Take(numberToShow)
.ToList();
Sugeriría un IOrderedQueryable como resultado del Func, esto forzará en tiempo de compilación un OrderBy, porque por ejemplo paginación no le gusta las consultas no ordenadas. –
Davy, de acuerdo. Cambié el código para reflejar esto. –
Me tomó un par de minutos descubrir cómo funciona esto, pero al final es muy factible. –