entity-framework-4 - framework - linq to sql
El miembro de tipo especificado no es compatible con LINQ to Entities. Solo se admiten inicializadores, miembros de entidades y propiedades de navegaciĆ³n de entidades (5)
Antes que nada, debes entender cuál es el motivo de tu problema.
Para mí, tuve un modelo, así:
public class SessionGroup
{
public int Id { get; set; }
public int UserId { get; set; }
private DateTime beginDate;
private DateTime? endDate;
public DateTime BeginDate
{
get { return beginDate; }
set { beginDate = DateTimeHelper.ToUtc(value); }
}
public DateTime? EndDate
{
get { return endDate; }
set
{
if (value.HasValue)
endDate = DateTimeHelper.ToUtc(value.Value);
else
endDate = null;
}
}
public bool IsSessionOpen { get { return EndDate == null; } }
public bool IsSessionClosed { get { return !IsSessionOpen; } }
}
Más tarde en mi consulta, estaba tratando de hacer algo como:
...
.Where(usr => usr.Sessions.All(s => !s.IsSessionClosed))
El problema aquí, como puede suponer, está relacionado con IsSessionClosed
que es propiedad automática y no es el campo de la base de datos real, sin embargo, lo utilicé porque no sabía que no estaba relacionado con la columna DB real.
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);
}
Aquí estoy obteniendo una excepción:
El miembro de tipo especificado "Edad" no se admite en LINQ to Entities. Solo se admiten inicializadores, miembros de entidades y propiedades de navegación de entidades.
Donde la edad no está en la base de datos, es propiedad que creé en la clase clsProfileDate para calcular la edad a partir de la fecha de nacimiento. ¿Alguna solución para esto?
Mucha gente va a decir que esta es una respuesta incorrecta porque no es una buena práctica, pero también puedes convertirla en una lista antes de tu ubicación.
result = result.ToList().Where(p => date >= p.DOB);
La respuesta de Slauma es mejor, pero esto funcionaría también. Esto cuesta más porque ToList () ejecutará la consulta contra la base de datos y moverá los resultados a la memoria.
No puede usar propiedades que no están mapeadas en una columna de base de datos en una expresión Where
. Debe compilar la expresión en función de las propiedades mapeadas, como:
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
Como reemplazo de su propiedad Age
no mapeada, puede extraer esta expresión en un método estático como ese:
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;
}
}
Y luego úsalo de esta manera:
result = result.Where(clsProfileDate.IsOlderThan(from));
Olvidé seleccionar la columna (o establecer / asignar la propiedad a un valor de columna):
IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name };
Las llamadas queryable.OrderBy("Id")
arrojarán una excepción, aunque DataModel
tiene el Id
. De propiedad definido.
La consulta correcta es:
IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name, Id = t.Id };
También recibirá este mensaje de error cuando se olvide accidentalmente de definir un setter para una propiedad. Por ejemplo:
public class Building
{
public string Description { get; }
}
var query =
from building in context.Buildings
select new
{
Desc = building.Description
};
int count = query.ToList();
La llamada a ToList dará el mismo mensaje de error. Este es un error muy sutil y muy difícil de detectar.