web-dev-qa-db-fra.com

Le membre de type spécifié 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.

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?

54
Sarang Amrutkar

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));
75
Slauma

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. 

16
Tony

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. 

9
Marcel Gelijk

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 };
1
Hp93

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);
0
Arash MAS