web-dev-qa-db-ja.com

EF COREと同等のDbFunctions.TruncateTime LINQ

私の.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を使っています。

16
TarasBulba

EF6では、何らかの理由で後者がサポートされていないため、DbFunctions.TruncateTimeプロパティの代わりにDateTime.Dateが使用されます。

EF Coreでは、DateTime.Dateが正しく認識および翻訳されるようになったため、前者は必要ありません。

group events by events.DateTimeFrom.Date into dateGroup

残念ながら、サポートされているものの(まだ)ドキュメントはありません。そのため、一般的な経験則として、対応するCLRメソッド/プロパティ(存在する場合)を常に試し、SQLに変換されるかどうかとその方法を確認してください。

44
Ivan Stoev

DbFunctionsは、EF Coreではまだサポートされていません。ただし、「Raw Sqlクエリ」を使用できます。

"Raw Sql Queries"のドキュメントはここにあります

また、EF CoreのDbFunctionsについて here を追跡することもできます

4
kizilsu

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 の詳細

1
M.R.T2017

これを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);
0
TarasBulba

EF Core 2.0は、データベース関数をコンテキスト上の静的メソッドにマッピングできるようになりました。

こちらの「データベーススカラー関数のマッピング」のセクションをご覧ください- https://docs.Microsoft.com/en-us/ef/core/what-is-new/

0
Paul

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()
                            });
0
Gareth