Sto utilizzando .NET e Entity Framework. Voglio raggruppare una tabella per una data senza la parte relativa all'ora.Entity framework group per data e ritorno nuova classe
Ho la classe:
public sealed class QueryItem {
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
}
E il metodo (sto usando il BLToolkit, se si vuole sapere che cosa è DBManager):
protected override IQueryable<QueryItem> InitiateQuery() {
return
from query in DbManager.GetTable<SomeTableModel>()
group query by new { Year = query.CreationDate.Year, Month = query.CreationDate.Month, Day = query.CreationDate.Day }
into list1
select new QueryItem {Year = list1.Key.Year, Month = list1.Key.Month, Day = list1.Key.Day};
}
In questo metodo LINQ tradotto in questa query SQL:
SELECT
[query].[CreationDate]
FROM
[SomeDatabase.SomeTable] [query]
GROUP BY
DatePart(Year, [query].[CreationDate]),
DatePart(Month, [query].[CreationDate]),
DatePart(Day, [query].[CreationDate]),
[query].[CreationDate]
E questa è una query errata perché non raggruppa solo per una data.
Ma se io uso questo codice (non è utilizzabile, ho bisogno di restituire un oggetto di classe):
var result =
from query in DbManager.GetTable<SomeTableModel>()
group query by new { Year = query.CreationDate.Year, Month = query.CreationDate.Month, Day = query.CreationDate.Day }
into list1
select list1;
Sarà tradotto in questo modo:
SELECT
[t1].[c1] as [c11],
[t1].[c2] as [c21],
[t1].[c3] as [c31]
FROM
(
SELECT
DatePart(Year, [selectParam].[CreationDate]) as [c1],
DatePart(Month, [selectParam].[CreationDate]) as [c2],
DatePart(Day, [selectParam].[CreationDate]) as [c3]
FROM
[SomeDatabase.SomeTable] [selectParam]
) [t1]
GROUP BY
[t1].[c1],
[t1].[c2],
[t1].[c3]
E questo è il giusto query.
Suppongo che Entity Framework cerchi di ottimizzare la mia query o qualcosa del genere e questo è il motivo per cui ho ottenuto la query sbagliata.
Ho ragione? Lo sto facendo nel modo giusto? Cosa devo fare (magari usare la query SQL diretta o qualcos'altro)?
Suppongo che dovrebbe funzionare. Ma ha fallito con BLToolkit. Il messaggio di eccezione: _'TruncateTime (Convertire (selectParam.CreationDate))' non può essere convertito in SQL._ E la stacktrace: _ a BLToolkit.Data.Linq.Builder.ExpressionBuilder.ConvertToSql (contesto, espressione Espressione IBuildContext , Boolean unwrap) _ Dovrei pensare a come realizzare l'interfaccia utente del filtro in un altro modo. – colotiline
In EF si traduce in 'convert (datetime, convert (varchar (255), [DateField], 102), 102))'. Puoi usarlo per creare qualche funzione in BLT? Non mi è chiaro come BLT e EF collaborino. La documentazione BLT è davvero scarsa, purtroppo. –
Ho provato ad implementare il mio comparatore. Anche questo è fallito.È sempre cercare di ottimizzare la query e fallito. Ma ho usato un'altra interfaccia utente e un modo per filtrare i dati e ora tutto funziona. – colotiline