通常,我具有某个日期范围内的报告数据,并且我想插入新的数据,并删除同一时期的旧数据。
我想在postgresql db中使用daterange类型的列。 我正在为PostgreSQL使用最新版本的EF。 我希望能够将我的字段映射到某些属性。 我希望能够根据此列选择,删除和插入新内容。
我试图将上下文映射到: 公共NpgsqlRange month_year {get;组; } 但有一个例外:“列“ month_year”的类型为daterange,但表达式的类型为tsrange” –我知道它正在发生,因为映射是这样工作的:NpgsqlRange => tsrange
我尝试使用: NpgsqlRange 但是下一个例外: 属性“ DBTable1.DateRangeNoda”的类型为“ NpgsqlRange”,当前的数据库提供程序不支持该属性,但是这不应该已经起作用了吗? 所以我的问题是:在.net core中有没有办法使用EF的daterange类型的列?如何?
using (var context = new postgresContext())
{
var d = new DBTable1(){Text = "aaa" };
d.DateRange1 = new NpgsqlRange<DateTime>(DateTime.Today, DateTime.Today);
//d.DateRangeNoda = new NpgsqlRange<LocalDate>
// (LocalDate.FromDateTime(DateTime.Today),
// LocalDate.FromDateTime(DateTime.Today) );
//efNpgsqlDate> not supported by provider
context.dbTable1.Add(d);
context.SaveChanges();
}
public partial class DBTable1
{
[Column("id")]
public int Id { get; set; }
public NpgsqlRange<DateTime> DateRange0 { get; set; }
public NpgsqlRange<LocalDate> DateRangeNoda { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DBTable1>(entity =>
{
entity.ToTable("test1");
entity.Property(e => e.DateRange1).HasColumnName("daterange1");
entity.Property(e => e.DateRangeNoda).HasColumnName("daterange");
});
}
现在我最终使用带有FirstOfTheRange date的date列:(
谢谢您的帮助,
答案 0 :(得分:1)
上面的代码示例中似乎有些混乱-您正在访问属性DateRange1
,而DBTable1类似乎包含DateRange0
。
Npgsql支持两种与日期/时间类型进行交互的方式:内置的BCL类型(例如DateTime)和the NodaTime library。支持内置的DateTime类型,但是默认将其映射到PostgreSQL timestamp
而不是date
,因为它具有时间分量。因此,类型为NpgsqlRange<DateTime>
的属性将导致Npgsql创建一个tsrange
列(时间戳范围),而不是daterange
)。可以将daterange
明确指定为列类型,但是与此相关的问题(see this comment会遇到一些细微问题。
如果使用NodaTime是可以的,那么事情应该会更好,因为NodaTime具有仅日期的类型-LocalDate
-因此NpgsqlRange<LocalDate>
自动映射到daterange
。为此,您将需要使用NodaTime插件as specified in the docs。
下面是一个完整的代码示例,用于在NodaTime中使用日期范围,包括插入和查询:
class Program
{
static void Main(string[] args)
{
using (var ctx = new BlogContext())
{
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();
ctx.Blogs.Add(new Blog { Duration = new NpgsqlRange<LocalDate>(new LocalDate(2011, 1, 1), new LocalDate(2011, 1, 3)) });
ctx.SaveChanges();
var x = ctx.Blogs.FirstOrDefault(b => b.Duration.Contains(new LocalDate(2011, 1, 2)));
}
}
}
public class BlogContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseNpgsql("<connection string>", o => o.UseNodaTime());
public DbSet<Blog> Blogs { get; set; }
}
public class Blog
{
public int Id { get; set; }
public NpgsqlRange<LocalDate> Duration { get; set; }
}
答案 1 :(得分:0)
问题是NodaTime使用了错误的软件包:
<!--Wrong one <PackageReference Include="Npgsql.NodaTime" Version="4.0.5" /> --> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
<!--Good one -->
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="2.2.0" />