私の.netアプリに次の機能しているLINQがあります
public ActionResult Index()
{
Dictionary<DateTime?, List<Event>> result;
result = (from events in db.Events.Include("Activity")
where events.IsActive
group events by DbFunctions.TruncateTime(events.DateTimeFrom) into dateGroup
select new { EventDate = dateGroup.Key, Events = dateGroup.ToList() }).ToDictionary(x => x.EventDate, x => x.Events);
return View(result);
}
EF Coreでこれを使用すると、DbFunctionsを使用できません。これを書き換えてMicrosoft.EntityFrameworkCoreで機能させるにはどうすればよいですか?それが違いを生むなら、私はSQLiteを使っています。
EF6では、何らかの理由で後者がサポートされていないため、DbFunctions.TruncateTime
プロパティの代わりにDateTime.Date
が使用されます。
EF Coreでは、DateTime.Date
が正しく認識および翻訳されるようになったため、前者は必要ありません。
group events by events.DateTimeFrom.Date into dateGroup
残念ながら、サポートされているものの(まだ)ドキュメントはありません。そのため、一般的な経験則として、対応するCLRメソッド/プロパティ(存在する場合)を常に試し、SQLに変換されるかどうかとその方法を確認してください。
DbFunctionsは、EF Coreではまだサポートされていません。ただし、「Raw Sqlクエリ」を使用できます。
"Raw Sql Queries"のドキュメントはここにあります
また、EF CoreのDbFunctionsについて here を追跡することもできます
ASP.NET COREでDbFunctionsを使用するにはオブジェクトを作成する必要があります。
var DbF = Microsoft.EntityFrameworkCore.EF.Functions;
これで簡単に使用できます。
var now = DateTime.Now;
int count = db.Tbl.Count(w => DbF.DateDiffDay(now, w.RegisterDate) <= 3);
github の詳細
これをLambdaでも書き直して非同期にしました。同じように働いているようです。
var temp = await _context.Events.Where(x => x.IsActive)
.Include(a => a.Activity)
.GroupBy(x => x.DateTimeFrom.Date)
.Select(g => new { EventDate = g.Key, Events = g.ToList() }).ToDictionaryAsync(x => x.EventDate, x => x.Events);
EF Core 2.0は、データベース関数をコンテキスト上の静的メソッドにマッピングできるようになりました。
こちらの「データベーススカラー関数のマッピング」のセクションをご覧ください- https://docs.Microsoft.com/en-us/ef/core/what-is-new/
EF Core 3.0
うまくいく答えをようやく見つけました。問題は、データベースのDateTime列の日付でグループ化したかったことです。
私にとっての鍵は、EF.Property関数を使用することでした。これにより、クラスはそのレベルのデータを追加するために使用されるDateTimeプロパティを持つことができますが、以下ではそれを日付として再定義することができました。ただし、クラスのプロパティをデカールした場合、それによって.Date関数を使用できるようになったのではないかと思います。
そのため、解決策は、モデルのプロパティを定義するか、以下を使用してクエリでプロパティを定義することです。
EF.Property(s、 "dt")。Date
完全なコード
var myData = _context.ActivityItems
.GroupBy(a => new { nlid = a.lid, nsd = EF.Property<DateTime>(a, "dt").Date })
.Select(g => new
{
g.Key.nlid,
g.Key.nsd,
cnt = g.Count()
});