Luk*_*988 3 entity-framework npgsql ef-core-2.2
I have a string array column in database
ALTER TABLE sample ADD languages VARCHAR[] NULL;
Run Code Online (Sandbox Code Playgroud)
which is mapped to model:
public string[] languages { get; set; }
Run Code Online (Sandbox Code Playgroud)
Using EF Core with PostgreSQL (Npgsql.EntityFrameworkCore.PostgreSQL 2.2.0) works out of the box.
However, when I want to test DbContext using In-Memmory (Microsoft.EntityFrameworkCore.InMemory 2.2.4) I got this error:
System.InvalidOperationException: 无法映射属性“sample.languages”,因为它的类型“string[]”不是受支持的基本类型或有效的实体类型。显式映射此属性,或使用 '[NotMapped]' 属性或使用 'OnModelCreating' 中的 'EntityTypeBuilder.Ignore' 忽略它。
因此,将其添加到模型构建器配置中可以解决 In-Memory 错误:
builder.Property(p => p.languages)
.HasConversion(
v => string.Join("'", v),
v => v.Split(',', StringSplitOptions.RemoveEmptyEntries));
Run Code Online (Sandbox Code Playgroud)
但引发了新的(Npgsql):
无法在 Npgsql.NpgsqlDefaultDataReader.GetFieldValue[T](Int32 列)处将数据库类型字符变化 [] 转换为字符串
请问您有什么提示吗?
没有多少数据库支持开箱即用的数组类型列。实际上 PostgreSQL 可能是目前支持的数据库中唯一一个这样做的。根据原始异常,显然内存数据库也不支持它(当前)。
EF Core 为每种数据库类型构建单独的模型。每个数据库提供程序公开的扩展方法DatabaseFacade等IsSqlServer(),IsNpgsql(),IsInMemory()等,它们可以用于内部OnModelCreating有条件地配置不同的映射,如果需要特定的数据库类型。
预期用途是这样的:
modelBuilder.Entity<Sample>(builder =>
{
if (!Database.IsNpgsql()) // <--
{
builder.Property(p => p.languages)
.HasConversion(
v => string.Join("'", v),
v => v.Split(',', StringSplitOptions.RemoveEmptyEntries));
}
});
Run Code Online (Sandbox Code Playgroud)
如果您使用单独的类实现IEntityTypeConfiguration<TEntity>来配置模型,那么您应该将 传递Database给它们的构造函数并存储在类成员中,因为EntityTypeBuilder<TEntity>传递给Configure方法的 不提供此类信息。
| 归档时间: |
|
| 查看次数: |
1213 次 |
| 最近记录: |