创建实体框架核心值转换器:属性'Remark'的类型为 'string'当前数据库提供程序不支持



我有我的内部域,它有一个string属性注释。在我的数据库中,我想将空string存储为NULL,当我从数据库加载NULL时,我希望这是一个空string

我想我会创建一个ValueConverter并注册它,就是这样。

public class StringEmptyToNullConverter : ValueConverter<string, string>
{
public StringEmptyToNullConverter() : base(ToDatabaseValue, ToDomainValue) {}
private static readonly Expression<Func<string, string>> ToDatabaseValue =
domainValue => string.IsNullOrWhiteSpace(domainValue) ? null : domainValue;
private static readonly Expression<Func<string, string>> ToDomainValue = databaseValue =>
databaseValue ?? string.Empty;
}

在我的上下文配置中,我将其注册为builder.Property(x => x.Remark).HasConversion(new StringEmptyToNullConverter());,它仍然在数据库中存储一个空string或给我一个NULL值。基本上,这会被忽略。

或者我将其注册为builder.Property(x => x.Opmerking).HasConversion<StringEmptyToNullConverter>();,这会引发错误:

属性">

备注"的类型为"字符串",当前数据库提供程序不支持该属性。更改属性 CLR 类型,或使用"[NotMapped]"属性或使用"OnModelCreateating"中的"EntityTypeBuilder.Ignore"忽略该属性。

有谁知道为什么我在转换器中做错了什么?

另外:当我在 lambda 语句中放置断点时,永远不会命中断点。

我还尝试了非常谨慎地注册 lambda:...HasConversion(domainValue => string.IsNullOrWhiteSpace(domainValue) ? null : domainValue, databaseValue => databaseValue ?? string.Empty);这与第一次注册的结果相同。

有两个问题阻止此操作。 鉴于:

modelBuilder.Entity<Customer>()
.Property(c => c.Name)
.HasConversion(
ev => ev==""?null:ev, 
dv => dv==null?"":dv
);

首先,查询的值转换不会将谓词转换为is null,它只是生成= null,在标准SQL中,该在标准SQL中永远不会匹配任何行,因为null = null计算结果为unknown,例如

像这样的查询:

var q2 = from cust in db.Customers
where cust.Name == ""
select cust;

翻译为

SELECT [c].[Id], [c].[Name]
FROM [Customers] AS [c]
WHERE [c].[Name] = NULL

其次,值覆盖者无法将数据库中的 null 转换为 .NET 中的 ":

此外,值转换器通常不允许转换 null 到其他一些值。这是因为相同的值转换器可以是 用于可为空和不可为空的类型,这非常有用 对于 PK/FK 组合,其中 FK 通常可为空且 PK 为 不。我们将讨论是否添加对转换的支持 空值。

https://github.com/dotnet/efcore/issues/13850

这目前根本行不通。 因此,不想混合空字符串和 null(您不想),如果您希望实体和数据库之间的一致性,您唯一的选择是在两个位置都使用 null。

相关内容

  • 没有找到相关文章