2009-02-20 105 views
55

Estoy tratando de determinar el número de días entre 2 fechas usando LINQ con Entity Framework. Me está diciendo que no reconoce Restar en la clase System.TimeSpanLINQ a entidades para restar 2 fechas

Aquí está mi parte where de la consulta LINQ.

where ((DateTime.Now.Subtract(vid.CreatedDate).TotalDays < maxAgeInDays)) 

Aquí está el error que recibo en el depurador VS.NET

método { "LINQ a Entidades no reconoce el método 'System.TimeSpan Restar (System.DateTime)', y esto método no se puede traducir a una expresión de tienda. "}

¿Estoy haciendo algo mal o hay una mejor manera de obtener el número de días entre 2 DateTimes en el marco de entidad?

gracias Michael

+0

También trató de evitar lapso de tiempo cambiando la fórmula un poco a la siguiente - que todavía no funciona donde (vid.CreatedDate.AddDays (maxAgeInDays)> = DateTime.Now) –

Respuesta

41

Aquí es cómo llegué a trabajar

he definido una variable de fecha y hora que representa la fecha más antigua

DateTime oldestDate = DateTime.Now.Subtract(new TimeSpan(maxAgeInDays, 0, 0, 0, 0)); 
... 

luego modificó la parte en la que de la consulta LINQ

where (vid.CreatedDate >= oldestDate) 

funcionó como un amuleto - gracias Micah por hacerme pensar sobre el árbol de expresión

+2

Debería haber marcado @Micah como respuesta y agregar un comentario a su respuesta o actualizar su pregunta con la respuesta final. – ongle

+0

Inteligente, listo inteligente. Simple y directo. Todavía me pregunto por qué no vino a mí en primer lugar. Gracias por compartir –

11

se encuentra con este tipo de isses porque el predicado debe ser traducido a un árbol de expresión. Y el proceso de traducción no reconoce el método DateTime.Now.Subtract.

+0

¿Hay alguna forma de hacer lo Estoy tratando de hacerlo para poder traducirme a un árbol de expresiones. –

1

El hecho es que, por diseño, LINQ to Entities necesita traducir toda la consulta a sentencias SQL. Ahí es donde no puede reconocer el método de Restar. Ocurrirá cada vez que intente utilizar un método C#/VB dentro de una consulta. En estos casos, debe encontrar una manera de sacar esa parte de la consulta. Este post explica un poco más: http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx

+0

Esta respuesta es correcta, pero definitivamente no es la respuesta que quería. LINQ to SQL admitió llamar a métodos externos tanto como quisiste, por lo que esta compensación es desafortunada. –

+2

el enlace está muerto. – Bijan

90

La respuesta aceptada es mejor en este caso, pero como referencia se puede utilizar la clase EntityFunctions para realizar operaciones en las fechas, entre otras cosas.

where (vid.CreatedDate >= EntityFunctions.AddDays(DateTime.Now, -maxAgeInDay)) 
+0

Gracias, esto es exactamente lo que estaba buscando. – wdanda

+3

Tenga en cuenta que esto solo es compatible con Entity Framework v4. Esto no funcionará para Entity Framework v1. –

+0

Gracias por compartir la clase EntityFunctions. Muy útil – StackThis

18

También puede utilizar System.Data.Objects.EntityFucntions:

currentDate = DateTime.Now; 

... 
where EntityFunctions.DiffDays(currentDate, vid.CreatedDate) < maxAgeIdDays 

Todas las funciones de EntityFunctions son sólo para LINQ-a-entidades y se asignan a las funciones SQL.

+0

También funcionan para Linq en entidades. –

+0

@Morten: Eso era tipo, solo funcionan con Linq-to-entities. –

+0

Muchas funciones específicas de SQL Server están disponibles a través de la clase 'System.Data.Objects.SqlClient.SqlFunctions'. Por supuesto, el almacén de datos tiene que ser un servidor SQL para que esto funcione. Más información: http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx – bernhof

0

Es posible definir una nueva propiedad en su modelo:

public DateTime StartDate{ get; set; } 
    public DateTime EndDate{ get; set; } 
    public TimeSpan CalculateTime{ 
     get 
     { 
      return EndDate.Subtract(StartDate); 
     } 
    } 

Ahora, usted puede usar algo así:

var query = from temp in db.Table 
select new MyModel { 
    Id = temp.Id, 
    Variable1 = temp.Variable1, 
    ... 
    EndDate = temp.EndDate, 
    StartDate = temp.StartDate 
} 

Cuando se tiene mirada en consecuencia, es posible utilizar el rendimiento, tales como:

return query 

Ahora, en la consulta, tenemos CalculateTime (reste entre EndDate y Startdate).