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);
}
Ici, je reçois une exception:
Le membre de type spécifié "Age" n'est pas pris en charge dans LINQ to Entities . Seuls les initialiseurs, les membres d'entité et les propriétés de navigation d'entité sont pris en charge.
Lorsque Age n’est pas dans la base de données, c’est la propriété que j’ai créée dans la classe clsProfileDate pour calculer Age à partir de la date de naissance. Une solution à cela?
Vous ne pouvez pas utiliser de propriétés qui ne sont pas mappées sur une colonne de base de données dans une expression Where
. Vous devez générer l'expression en fonction des propriétés mappées, telles que:
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
En remplacement de votre propriété Age
non mappée, vous pouvez extraire cette expression dans une méthode statique comme ceci:
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;
}
}
Et puis utilisez-le de cette façon:
result = result.Where(clsProfileDate.IsOlderThan(from));
Beaucoup de gens vont dire que c'est une mauvaise réponse car ce n'est pas la meilleure pratique, mais vous pouvez également le convertir en liste avant votre emplacement.
result = result.ToList().Where(p => date >= p.DOB);
La réponse de Slauma est meilleure, mais cela fonctionnerait aussi. Cela coûte plus cher car ToList () exécutera la requête sur la base de données et déplacera les résultats en mémoire.
Vous obtiendrez également ce message d'erreur si vous oubliez par inadvertance de définir un générateur pour une propriété . Par exemple:
public class Building
{
public string Description { get; }
}
var query =
from building in context.Buildings
select new
{
Desc = building.Description
};
int count = query.ToList();
L'appel à ToList donnera le même message d'erreur. Celui-ci est une erreur très subtile et très difficile à détecter.
J'ai oublié de sélectionner la colonne (ou de définir/mapper la propriété sur une valeur de colonne):
IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name };
L'appel de queryable.OrderBy("Id")
lancera une exception, même si DataModel
a la propriété Id
définie.
La requête correcte est:
IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name, Id = t.Id };
Dans ce cas, l’une des méthodes les plus simples et les meilleures consiste à le convertir en list
, puis à utiliser where
ou select
.
result = result.ToList().where(p => date >= p.DOB);