update query framework consulta columns linq entity-framework

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.



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.

  1. Busque una propiedad [NotMapped] con el nombre Foo en su modelo de base de datos.
  2. Busque una propiedad con el mismo nombre, Foo , en su Modelo de Vista.
  3. 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 miembro not auto calculated para have propiedades getter y setter


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.