Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果NodaTime使用Duration,Postgres使用INTERVAL/Period,那么如何在efcore中执行时间戳算法?_C#_Postgresql_Entity Framework Core_Npgsql_Nodatime - Fatal编程技术网

C# 如果NodaTime使用Duration,Postgres使用INTERVAL/Period,那么如何在efcore中执行时间戳算法?

C# 如果NodaTime使用Duration,Postgres使用INTERVAL/Period,那么如何在efcore中执行时间戳算法?,c#,postgresql,entity-framework-core,npgsql,nodatime,C#,Postgresql,Entity Framework Core,Npgsql,Nodatime,在我的.NET Core 3.1项目中,我目前正在将与时间相关的代码移动到NodaTime 我在翻译一些查询时遇到了问题,因为NodaTime中两个瞬间之间的差异会产生一个持续时间,而Postgres中两个时间戳之间的差异会产生一个间隔 Npgsql将瞬间映射为时间戳,但间隔是一个周期 假设我有一个名为“访问”的实体,它有一个ID,有两次:“到达”和“离开”。(这不是我的实际用例,我有几个实体有这个问题,所以这是一个最小的例子) 现在我想找到访客停留时间少于给定时间的访问: public asy

在我的.NET Core 3.1项目中,我目前正在将与时间相关的代码移动到NodaTime

我在翻译一些查询时遇到了问题,因为NodaTime中两个瞬间之间的差异会产生一个持续时间,而Postgres中两个时间戳之间的差异会产生一个间隔

Npgsql将瞬间映射为时间戳,但间隔是一个周期

假设我有一个名为“访问”的实体,它有一个ID,有两次:“到达”和“离开”。(这不是我的实际用例,我有几个实体有这个问题,所以这是一个最小的例子)

现在我想找到访客停留时间少于给定时间的访问:

public async Task<List<Visit>> FindVisitsShorterThan(DbSet<Visit> dbSet, Duration duration)
{
    var visits =
        from visit in dbSet
        where (visit.Left - visit.Arrived) < duration
        select visit;
    return await visits.ToListAsync();
}
公共异步任务findvisitsshorthan(DbSet-DbSet,Duration-Duration)
{
var访问=
来自dbSet的访问
地点(访问左-访问到达)<持续时间
选择访问;
回访等待访问。ToListSync();
}
如果我这样做,Npgsql会抱怨类似于System.InvalidCastException的问题:无法使用处理程序类型TimestampHandler写入CLR类型的NodeTime.Duration,因为不支持durations

另一方面,如果我将持续时间转换为一个周期,NodaTime会抱怨,因为从它的角度来看,这种差异是一个持续时间,不能与 我可以做几件事,但似乎没有一件是理想的:

  • 更改实体并将“Instant Left”替换为“Period Stay”,这样我就不必在查询中进行计算。但这只适用于一个特定的查询-如果我需要“左”用于另一个查询怎么办
  • 仅使用LocalDateTime而不是Instant。不同的是一个周期,所以这在NodaTime和Postgres中都适用。但这样我就改变了实体的语义——我希望这些时间是UTC时间戳,这是有原因的。LocalDateTime本质上意味着“TZ未知或存储在别处”,这根本不是真的
  • 恢复到BCL类型并再次开始与时区作战
  • 将我的实体拆分为具有Instant的域类型和具有LocalTime的Npgsql特定DTO类型,并在它们之间进行一些映射。可能是最好的解决方案,但似乎没有必要

有更好的方法吗?

这确实是当前Npgsql EF对节点时间类型支持的一个不幸限制


好消息是,我刚刚实现了上述功能,以及其他一些NodaTime算术翻译-。这将包含在下周即将发布的EF Core 5.0版本中-请稍等几天,一切都会好起来。

Hmm。我不知道Npgsql如何转换查询。。。我认为最好的解决办法是,通过将
持续时间
转换为Postgres
间隔
来处理现有查询。我怀疑如果不更改Npgsql,您很难得到好的代码。即使有办法将表达式转换为查询,结果查询也是不可搜索的。您最好预先计算该值并将其存储在单独的列中。因此。。。这是我关于stackoverflow的第一个问题。我没抱多大期望。但不到两天,我就收到了Jon Skeet的评论,我的问题由Npgsql所有者自己解决了。非常感谢你!无论如何,我正准备升级到.NET5,所以这是最好的时机。
public async Task<List<Visit>> FindVisitsShorterThan(DbSet<Visit> dbSet, Duration duration)
{
    var visits =
        from visit in dbSet
        where (visit.Left - visit.Arrived) < duration
        select visit;
    return await visits.ToListAsync();
}