linq - query - Solo se admiten inicializadores, miembros de entidades y propiedades de navegación de entidades
linq to entities (7)
Linq convierte las declaraciones en declaraciones SQL y las ejecuta en la base de datos.
Ahora, esta conversión solo ocurre para miembros de entidades, inicializadores y propiedades de navegación de entidad. Por lo tanto, para lograr una función u obtener una comparación de propiedades, primero debemos convertirlas en listas en memoria y luego aplicar funciones para recuperar datos.
Por lo tanto, en su totalidad,
var debts = storeDB.Orders.toList()
.Where(o => o.Paid == false)
.OrderByDescending(o => o.DateCreated);
Me sale esta excepción:
El miembro de tipo especificado ''Pagado'' no se admite en LINQ to Entities. Solo se admiten inicializadores, miembros de entidades y propiedades de navegación de entidades.
public ActionResult Index()
{
var debts = storeDB.Orders
.Where(o => o.Paid == false)
.OrderByDescending(o => o.DateCreated);
return View(debts);
}
Mi clase de modelo
public partial class Order
{
public bool Paid {
get {
return TotalPaid >= Total;
}
}
public decimal TotalPaid {
get {
return Payments.Sum(p => p.Amount);
}
}
Pagos es una tabla relacionada que contiene el monto del campo. La consulta funciona si elimino la cláusula Where que muestra la información correcta sobre los pagos, ¿alguna pista de qué es lo que falla con el código?
Resuelto como la respuesta sugerida con:
public ActionResult Index()
{
var debts = storeDB.Orders
.OrderByDescending(o => o.DateCreated)
.ToList()
.Where(o => o.Paid == false);
return View(debts);
}
Entity está tratando de convertir su propiedad Paid a SQL y no puede porque no es parte del esquema de la tabla.
Lo que puede hacer es dejar que la entidad consulte la tabla sin filtro Pagado y luego filtrar los que no son Pagos.
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);
}
Eso, por supuesto, significaría que traerá todos los datos al servidor web y filtrar los datos en él. Si desea filtrar en el servidor de bases de datos, puede crear una columna calculada en la tabla o usar un procedimiento almacenado.
Esta situación también puede ocurrir si está utilizando los tipos de EntityFramework no compatibles , como unsigned int.
Este fue mi caso de tal error.
Obtenga más información sobre tipos admitidos: https://msdn.microsoft.com/en-us/library/ee382832(v=vs.100).aspx
Hay alguna solución para tales situaciones, explicada por GFoley83: ¿Cómo usar unsigned int / long types con Entity Framework?
Este problema también puede provenir de una propiedad [NotMapped]
que tiene el mismo nombre en su Modelo de BD y Modelo de Vista.
AutoMapper intenta seleccionarlo del DB durante una proyección; y la propiedad NotMapped obviamente no existe en el DB.
La solución es Ignore
la propiedad en la configuración de AutoMapper al mapear desde el Modelo de BD al Modelo de Vista.
- Busque una propiedad
[NotMapped]
con el nombreFoo
en su modelo de base de datos. - Busque una propiedad con el mismo nombre,
Foo
, en su Modelo de Vista. - Si ese es el caso, entonces cambie su configuración de AutoMapper. Agregue
.ForMember(a => a.Foo, b => b.Ignore());
La otra razón probable es porque está usando IEnumerable
para su propiedad, en lugar de ICollection
Entonces, en lugar de:
public class This
{
public long Id { get; set; }
//...
public virtual IEnumerable<That> Thats { get; set; }
}
Hacer esto:
public class This
{
public long Id { get; set; }
//...
public virtual ICollection<That> Thats { get; set; }
}
Y eres un maldito loco ... estúpido de perder 2 horas más ...
Me enfrenté a este problema porque estaba teniendo una variable miembro con solo get
without set
propiedad
eso significa que se auto calculated
y not stored
como una columna en the table
por lo tanto, not exist
en el table schema
la table schema
así
make sure
que cualquier variable miembronot auto calculated
parahave
propiedadesgetter
ysetter
Solo tuve que resolver un problema similar. Las soluciones anteriores requieren un procesamiento en memoria, lo cual es una mala práctica (carga diferida).
Mi solución fue escribir un ayudante que devolviera un predicado:
public static class Extensions
{
public static Expression<Func<Order, bool>> IsPaid()
{
return order => order.Payments.Sum(p => p.Amount) >= order.Total;
}
}
Puede volver a escribir su declaración linq como:
var debts = storeDB.Orders
.Where(Extensions.IsPaid())
.OrderByDescending(o => o.DateCreated);
Esto es útil cuando quiere reutilizar la lógica de cálculo (DRY). Lo malo es que la lógica no está en su modelo de dominio.