web-dev-qa-db-fra.com

Le type de membre spécifié 'Date' n'est pas pris en charge dans LINQ to Entities Exception

J'ai eu une exception lors de la mise en œuvre des déclarations suivantes.

 DateTime result;
 if (!DateTime.TryParse(rule.data, out result))
     return jobdescriptions;
 if (result < new DateTime(1754, 1, 1)) // sql can't handle dates before 1-1-1753
     return jobdescriptions;
 return jobdescriptions.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );

exception

The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Je sais ce que l'exception signifie, mais je ne sais pas comment m'en débarrasser. De l'aide?

99
nebula

LINQ to Entities ne peut pas traduire la plupart des méthodes Date .NET (y compris la conversion que vous avez utilisée) en SQL car il n’existe pas de code SQL équivalent.

La solution consiste à utiliser les méthodes Date en dehors de l'instruction LINQ, puis à transmettre une valeur. Il semble que Convert.ToDateTime (rule.data) .Date soit à l'origine de l'erreur.

L'appel de Date sur une propriété DateTime ne peut pas non plus être traduit en SQL. Par conséquent, une solution de contournement consiste à comparer les propriétés .Year .Month et .Day pouvant être traduites en LINQ, car elles ne sont que des entiers.

var ruleDate = Convert.ToDateTime(rule.data).Date;
return jobdescriptions.Where(j => j.Deadline.Year == ruleDate.Year 
                       && j.Deadline.Month == ruleDate.Month 
                       && j.Deadline.Day == ruleDate.Day);
99
Judo

Vous pouvez utiliser la méthode TruncateTime de la EntityFunctions pour obtenir une traduction correcte de la propriété Date en SQL:

using System.Data.Objects; // you need this namespace for EntityFunctions

// ...

DateTime ruleData = Convert.ToDateTime(rule.data).Date;
return jobdescriptions
    .Where(j => EntityFunctions.TruncateTime(j.JobDeadline) == ruleData);


Mise à jour: EntityFunctionsest obsolète en EF6, utilisez DbFunctions.TruncateTime

217
Slauma

Pour EF6, utilisez plutôt DbFunctions.TruncateTime (mydate).

36
KingOfHypocrites

"EntityFunctions.TruncateTime" ou "DbFunctions.TruncateTime" dans ef6 fonctionne mais présente des problèmes de performances dans Big Data.

Je pense que le meilleur moyen est d'agir comme ceci:

DateTime ruleDate = Convert.ToDateTime(rule.data);

DateTime  startDate = SearchDate.Date;

DateTime  endDate = SearchDate.Date.AddDay(1);

return jobdescriptions.Where(j.Deadline >= startDate 
                       && j.Deadline < endDate );

c'est mieux que d'utiliser des parties de la date pour. parce que la requête est exécutée plus rapidement dans les grandes données.

8
Mahdi Shahbazi

Essayez d'utiliser

return jobdescriptions.AsEnumerable()
.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );

AsEnumerable() bascule le contexte de la requête de LINQ à Entities de LINQ à Objets afin que la condition ne soit pas convertie en SQL

2
Caleb Kiage

Cela signifie que LINQ to SQL ne sait pas comment transformer la propriété Date en une expression SQL. En effet, la propriété Date de la structure DateTime n'a pas d'analogue dans SQL.

1
Adam Robinson

Cela a fonctionné pour moi.

DateTime dt = DateTime.Now.Date;
var ord = db.Orders.Where
      (p => p.UserID == User && p.ValidityExpiry <= dt);

Source: Asp.net Forums

1
M.R.T2017

J'ai le même problème mais je travaille avec DateTime-Ranges. Ma solution est de manipuler l’heure de début (avec n’importe quelle date) à 00:00:00 et l’heure de fin à 23:59:59. Par conséquent, je ne dois plus convertir mon DateTime en Date, elle reste plutôt DateTime.

Si vous ne disposez que d'un DateTime, vous pouvez également définir l'heure de début (avec n'importe quelle date) sur 00:00:00 et l'heure de fin sur 23:59:59. Vous effectuez ensuite une recherche comme s'il s'agissait d'un intervalle de temps.

var from = this.setStartTime(yourDateTime);
var to = this.setEndTime(yourDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);

Vous pouvez le faire aussi avec DateTime-Range:

var from = this.setStartTime(yourStartDateTime);
var to = this.setEndTime(yourEndDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);
0
peter70

vous pouvez obtenir Enum comme:

DateTime todayDate = DateTime.Now.Date; var check = db.tableName.AsEnumerable().Select(x => new
        {
            Date = x.TodayDate.Date
        }).Where(x => x.Date == todayDate).FirstOrDefault();
0
Omid Soleiman