EF Core NodaTime 字段 - 无法映射
EF Core NodaTime field - could not be mapped
我在 <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
中使用 EF Core
我刚刚向我的实体添加了一个 NodaTime.LocalDate
字段,该字段使用名为 NodaTime 的包:
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="5.0.2" />
字段:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Nest;
namespace Vepo.Domain
{
[ElasticsearchType(RelationName = "eventitem", IdProperty = "Id")]
public class EventItem : VeganItem<EventItemEstablishment>
{
[MaxLength(10)]
public List<NpgsqlRange<LocalDateTime>> Dates { get; set; }
}
}
我现在收到这个错误:
InvalidOperationException: The property ‘EventItem.Dates’ could not be
mapped, because it is of type List<NpgsqlRange<LocalDateTime>>
which is not a supported
primitive type or a valid entity type. Either explicitly map this
property, or ignore it using the ‘[NotMapped]’ attribute or by using
‘EntityTypeBuilder.Ignore’ in ‘OnModelCreating’.
所以 Ef Core 无法映射 List。
这是一个演示,演示如何使用值转换器让 EF Core 映射 LocalDateTime
:
base.OnModelCreating(modelBuilder);
var localDateConverter =
new ValueConverter<LocalDate, DateTime>(v =>
v.ToDateTimeUnspecified(),
v => LocalDate.FromDateTime(v));
modelBuilder.Entity<Event>()
.Property(e => e.Date)
.HasConversion(localDateConverter);
但这对我不起作用,因为我的领域不是LocalDateTime
,而是List<NpgsqlRange<LocalDateTime>>
我正在努力正确创建值转换器。任何帮助表示赞赏。
仅供参考我的前端正在向后端发送自定义对象列表:[{DateTime startDate, DateTime endDate}]
重要提示: Shay Rojansky 的版本对我有用,我需要更改我的 Startup.cs
代码:
public void ConfigureServices(IServiceCollection services)
{
services
.AddDbContext<VepoContext>(opt => {
opt
.UseNpgsql(
Configuration
.GetConnectionString("DefaultConnection"))
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.LogTo(Console.WriteLine);
});
NpgsqlConnection.GlobalTypeMapper.UseNodaTime();
为此(基本上是他的 - 但我的初始化代码使用的是 ConfigureServices
,而不是 OnConfiguring
所以我想我会 post 他的解决方案 ConfigureServices
语法这里是为代码已经在使用 ConfigureServices
:
的人准备的
services
.AddDbContext<VepoContext>(opt => {
opt
.UseNpgsql(
Configuration
.GetConnectionString("DefaultConnection"),
o => o.UseNodaTime()
)
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.LogTo(Console.WriteLine);
});
以上使用 5.0.10 对我有效,没有值转换器:
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(@"Host=localhost;Username=test;Password=test", o => o.UseNodaTime())
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
public class Blog
{
public int Id { get; set; }
public List<NpgsqlRange<LocalDateTime>> Dates { get; set; }
}
创建了以下 table:
CREATE TABLE "Blogs" (
"Id" integer GENERATED BY DEFAULT AS IDENTITY,
"Dates" tsrange[] NULL,
CONSTRAINT "PK_Blogs" PRIMARY KEY ("Id")
);
您可能对即将发布的 PostgreSQL 14 版本中的新多范围类型感兴趣。对它的支持已添加到 EF Core 提供程序的 6.0 版中(PG14 和 EF Core 6.0.0 的候选版本已经发布),因此您可能想尝试一下。
我收到这个 'not a supported primitive type' 错误是因为我按照我的情况遵循了错误的文档。我从 https://www.npgsql.org/doc/types/nodatime.html 开始,它使用 NuGet 包 Npgsql.NodaTime
并使用 NpgsqlConnection.GlobalTypeMapper.UseNodaTime();
应用类型映射
我需要改为遵循 https://www.npgsql.org/efcore/mapping/nodatime.html 处的 EF Core 文档,它依赖于 NuGet 包 Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime
并通过 UseNodaTime()
在 NpgsqlDbContextOptionsBuilder
上应用类型映射
builder.UseNpgsql("Host=localhost;Database=test;Username=npgsql_tests;Password=npgsql_tests",
o => o.UseNodaTime());
我在 <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
我刚刚向我的实体添加了一个 NodaTime.LocalDate
字段,该字段使用名为 NodaTime 的包:
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="5.0.2" />
字段:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Nest;
namespace Vepo.Domain
{
[ElasticsearchType(RelationName = "eventitem", IdProperty = "Id")]
public class EventItem : VeganItem<EventItemEstablishment>
{
[MaxLength(10)]
public List<NpgsqlRange<LocalDateTime>> Dates { get; set; }
}
}
我现在收到这个错误:
InvalidOperationException: The property ‘EventItem.Dates’ could not be mapped, because it is of type
List<NpgsqlRange<LocalDateTime>>
which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the ‘[NotMapped]’ attribute or by using ‘EntityTypeBuilder.Ignore’ in ‘OnModelCreating’.
所以 Ef Core 无法映射 List
这是一个演示,演示如何使用值转换器让 EF Core 映射 LocalDateTime
:
base.OnModelCreating(modelBuilder);
var localDateConverter =
new ValueConverter<LocalDate, DateTime>(v =>
v.ToDateTimeUnspecified(),
v => LocalDate.FromDateTime(v));
modelBuilder.Entity<Event>()
.Property(e => e.Date)
.HasConversion(localDateConverter);
但这对我不起作用,因为我的领域不是LocalDateTime
,而是List<NpgsqlRange<LocalDateTime>>
我正在努力正确创建值转换器。任何帮助表示赞赏。
仅供参考我的前端正在向后端发送自定义对象列表:[{DateTime startDate, DateTime endDate}]
重要提示: Shay Rojansky 的版本对我有用,我需要更改我的 Startup.cs
代码:
public void ConfigureServices(IServiceCollection services)
{
services
.AddDbContext<VepoContext>(opt => {
opt
.UseNpgsql(
Configuration
.GetConnectionString("DefaultConnection"))
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.LogTo(Console.WriteLine);
});
NpgsqlConnection.GlobalTypeMapper.UseNodaTime();
为此(基本上是他的 - 但我的初始化代码使用的是 ConfigureServices
,而不是 OnConfiguring
所以我想我会 post 他的解决方案 ConfigureServices
语法这里是为代码已经在使用 ConfigureServices
:
services
.AddDbContext<VepoContext>(opt => {
opt
.UseNpgsql(
Configuration
.GetConnectionString("DefaultConnection"),
o => o.UseNodaTime()
)
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.LogTo(Console.WriteLine);
});
以上使用 5.0.10 对我有效,没有值转换器:
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(@"Host=localhost;Username=test;Password=test", o => o.UseNodaTime())
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
public class Blog
{
public int Id { get; set; }
public List<NpgsqlRange<LocalDateTime>> Dates { get; set; }
}
创建了以下 table:
CREATE TABLE "Blogs" (
"Id" integer GENERATED BY DEFAULT AS IDENTITY,
"Dates" tsrange[] NULL,
CONSTRAINT "PK_Blogs" PRIMARY KEY ("Id")
);
您可能对即将发布的 PostgreSQL 14 版本中的新多范围类型感兴趣。对它的支持已添加到 EF Core 提供程序的 6.0 版中(PG14 和 EF Core 6.0.0 的候选版本已经发布),因此您可能想尝试一下。
我收到这个 'not a supported primitive type' 错误是因为我按照我的情况遵循了错误的文档。我从 https://www.npgsql.org/doc/types/nodatime.html 开始,它使用 NuGet 包 Npgsql.NodaTime
并使用 NpgsqlConnection.GlobalTypeMapper.UseNodaTime();
我需要改为遵循 https://www.npgsql.org/efcore/mapping/nodatime.html 处的 EF Core 文档,它依赖于 NuGet 包 Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime
并通过 UseNodaTime()
在 NpgsqlDbContextOptionsBuilder
上应用类型映射
builder.UseNpgsql("Host=localhost;Database=test;Username=npgsql_tests;Password=npgsql_tests",
o => o.UseNodaTime());