Entity Framework Core - 具有转换 - 支持空值

Tal*_*umy 9 entity-framework entity-framework-core asp.net-core

我有一个带有通知电子邮件属性的 EF 模型。通知电子邮件以“;”分隔的字符串形式保存在数据库中。我添加了一个转换以将数据检索为模型中的 ICollection。这工作得很好,除了一件事:当字符串为空时,集合也为空,我想将其转换为空集合。是否可以?

//This is my code
  entity.Property(e => e.NotificationEmails)
             .HasConversion(
                v => string.Join(",", v.Select(s => s.Trim())),
                v => v.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
Run Code Online (Sandbox Code Playgroud)

我尝试添加 String.IsNullOrEmpty(v) 但 EF 忽略它。

Orw*_*wel 8

目前,这是不可能的:

https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions#configuring-a-value-converter

空值永远不会传递给值转换器。这使得转换的实现更加容易,并允许它们在可为空和不可为空的属性之间共享。

它并不优雅,但您可以使用支持字段:

public class Notification
{
    private List<string> _emails = new List<string>();
    public List<string> Emails 
    {
        get => _emails;
        set => _emails = value ?? new List<string>();
    }
}

public class NotificationContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Notification>().Property(d => d.Emails).HasConversion(
                v => string.Join(",", v.Select(s => s.Trim())),
                v => v.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList()
            );
            modelBuilder.Entity<Notification>()
                .Property(b => b.Emails)
                .HasField("_emails")
                .UsePropertyAccessMode(PropertyAccessMode.Property);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:在where中,空列表不会被null翻译,而是被空字符串翻译。

编辑:此功能可从 EF Core 6 获得,但存在缺陷。看到这个评论

对于关注此问题的任何人:执行将数据库中的空值转换为代码中的非空值或反之亦然的查询时,会出现重大问题。因此,我们已将此功能标记为 EF Core 6.0 的内部功能。您仍然可以使用它,但您会收到编译器警告。可以使用#pragma 禁用该警告。