如何在 Entity Framework 中计算 时间差 ?

咨询区

  • ison

我的项目中有一个需求,需要使用 Entity Framework 实现 日期差 的计算逻辑,参考如下代码:

var now = DateTime.UtcNow;

db.Items.OrderBy(x => x.SomeInteger + (x.Date - now).Days);

但很奇怪,上面的代码会抛下面的错误:

The LINQ expression 'orderby' could not be translated and will be evaluated locally.

在 .NET Framework 中我可以通过 DbFunctions.DiffDays 来实现此需求, 但在 ASP.NET Core 中我该如何实现呢?

回答区

  • Stephen LAI

在 github 上有一个 issue 就和你的问题相关,貌似在 2.1+ 后就已经修复了这个问题,github:https://github.com/dotnet/efcore/issues/10468

解决方案如下:

public static class DbUtility
{
    public static int DateDiff(string diffType, DateTime startDate, DateTime endDate)
    {
        throw new InvalidOperationException($"{nameof(DateDiff)} should be performed on database");
    }
}

然后修改 ApplicationDbContext 类。

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.HasDbFunction(typeof(DbUtility)
        .GetMethod(nameof(DbUtility.DateDiff)))
        .HasTranslation(args => {
            var newArgs = args.ToArray();
            newArgs[0] = new SqlFragmentExpression((string)((ConstantExpression)newArgs[0]).Value);
            return new SqlFunctionExpression(
                "DATEDIFF",
                typeof(int),
                newArgs);
        });
}

最后像下面这样使用。

DbUtility.DateDiff("day", x.DateAdded, now)
  • Stephen LAI

ASP.NET Core 中你完全可以使用 SQL 提供的原生函数,由原来的 DbFunctions.DiffDays 改成 EF.Functions.DateDiffDay 即可, 参考如下代码:

var lstPeople = cxt
.People.Where(p => EF.Functions.DateDiffDay(p.Birth, DateTime.Now) > 0 )
.ToList();

点评区

其实用 EntityFramework 我还是那句话,如果你的项目业务复杂度不是很高的化,完全可以使用 EF 是一点问题都没有的,一旦复杂度上去了,用 EF 反而是一种负担,比如:100行的Linq100行的sql ,哪一种会把你看晕呢?

为了使用 Entity FrameworkEF)连接 SQLite 数据库,你需要按照以下步骤操作: 1. **添加 NuGet 包**:打开你的 Visual Studio 项目,右键单击“管理NuGet程序包”,搜索并安装 `Microsoft.EntityFrameworkCore.Sqlite.Core` 和 `Microsoft.EntityFrameworkCore.Tools` 包。前者提供 EF 对 SQLite 的支持,后者包含了用于数据库迁移的命令行工具。 2. **配置连接字符串**:在 `appsettings.json` 文件或者单独的配置文件,添加一个 SQLite 的连接字符串,例如: ```json { "ConnectionStrings": { "DefaultConnection": "Data Source=mydatabase.sqlite;Version=3;" } } ``` 这里 `mydatabase.sqlite` 是你的数据库文件名,`Version=3` 表示使用 SQLite 3.x 版本。 3. **注册 DbContext**:在你的数据访问层,创建一个继承自 `DbContext` 的类,并在其声明 DbSet 对应于你的表: ```csharp public class MyDbContext : DbContext { public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } // 添加其他 DbSet 对象... } ``` 4. **启用迁移和生成模型**:在命令行运行 `dotnet ef migrations add InitialCreate` 生成针对 SQLite 的数据库迁移。然后,运行 `dotnet ef database update` 来应用迁移并初始化数据库。 5. **使用 DbContext**:现在你可以实例化并使用你的 `MyDbContext` 类来进行 CRUD 操作了。 记住,SQLite 的一些特性可能需要你在代码进行调整,因为它们可能与 EF 默认的行为有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值