使用新的映射规则扩展 EF 6.2

问题描述

NHibernate 可以使用 IUserType 的新实现进行扩展,因此我可以自定义如何从/从数据库读取和存储映射属性

一个例子。如果我希望 DB null varchar 加载为“n/a”字符串,而“n/a”字符串存储为 null

EF 6.2 如何做到这一点?

我正在寻找一种不会破坏变更跟踪器的解决方案。

解决方法

从 EF 6.2 开始,库没有提供这种开箱即用的功能。

如果您决定改用 EF Core,则可以使用 HasConversion 功能。

但是,在您的情况下,您仍然无法使用它,因为有一个警告:它不能用于转换 null 值。 Null 总是被转换为 null。来自docs

空值永远不会传递给值转换器。数据库列中的空值始终是实体实例中的空值,反之亦然。这使得转换的实现更容易,并允许它们在可为空和不可为空的属性之间共享。有关详细信息,请参阅 GitHub issue #13850

在这种情况下,我建议您将字符串属性配置为具有 Backing Field,而不是值转换。然后,您可以读取/写入私有支持字段,然后使用公共属性处理空值。

public class Blog
{
    private string _stringFromDb;

    public string MyString { get; set; }

    [BackingField(nameof(_stringFromDb))]
    public string MyString
    {
        get { return _stringFromDb ?? "n/a"; }
    }

    public void SetMyString(string myString)
    {
        // put your validation code here

        _stringFromDb = myString;
    }
}

在 EF 6.2 中,作为变通方法,您可以拥有的最接近的属性是 [NotMapped] 属性,它可以负责翻译您从数据库加载的属性。

public string StringDB { get; set; }

[NotMapped]
public string StringConverted
{ 
    get { return MyStringProperty ?? "n/a"; }
    set { MyStringProperty = value  }
}

除此之外,如果您想隐藏映射到您的数据库的属性,方法是将其设为 private,这不像使用 EF Core 的支持字段那么简​​单,但您可以遵循 this other answer有关如何实现它的说明。