值轉換

值轉換器允許在讀取或寫入資料庫時轉換屬性值。 這項轉換可以是從一個值轉換成另一個相同型別的值(例如加密字串),或從某個型別的值轉換成另一個型別的值(例如,將列舉值轉換成資料庫中的字串。

提示

您可以從 GitHub 下載範例程式碼,以執行並偵錯此文件中的所有程式碼。

概觀

值轉換器會以 和 ProviderClrTypeModelClrType 指定。 模型類型是實體類型中屬性的 .NET 類型。 提供者類型是資料庫提供者所瞭解的 .NET 類型。 例如,若要將列舉儲存為資料庫中的字串,模型類型是列舉的類型,而提供者類型為 String 。 這兩種類型可以相同。

轉換是使用兩 Func 個運算式樹狀結構來定義:一個從 ModelClrTypeProviderClrType ,另一個從 ProviderClrType 到 。 ModelClrType 運算式樹狀結構會使用,以便編譯成資料庫存取委派,以便有效率地轉換。 運算式樹狀結構可能包含對複雜轉換之轉換方法的簡單呼叫。

注意

已針對值轉換設定的屬性也可能需要指定 ValueComparer<T> 。 如需詳細資訊,請參閱下列範例和 值比較子 檔。

設定值轉換器

值轉換是在 中 DbContext.OnModelCreating 設定。 例如,請考慮定義為下列專案的列舉和實體類型:

public class Rider
{
    public int Id { get; set; }
    public EquineBeast Mount { get; set; }
}

public enum EquineBeast
{
    Donkey,
    Mule,
    Horse,
    Unicorn
}

轉換可以設定在 中 OnModelCreating ,以將列舉值儲存為字串,例如 「Donkey」、「Mule」 等。您只需要提供一個函式,以從 ModelClrTypeProviderClrType 轉換成 ,另一個函式進行相反轉換:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion(
            v => v.ToString(),
            v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));
}

注意

null值永遠不會傳遞至值轉換器。 資料庫資料行中的 Null 一律為實體實例中的 Null,反之亦然。 這可讓轉換的實作更容易,並允許在可為 Null 和不可為 Null 的屬性之間共用。 如需詳細資訊,請參閱 GitHub 問題 #13850

大量設定值轉換器

針對使用相關 CLR 類型的每個屬性,設定相同的值轉換器很常見。 您可以針對每個屬性手動執行這項操作,而不需要針對整個模型使用 預先慣例模型組態 來執行此動作。 若要這樣做,請將您的值轉換器定義為類別:

public class CurrencyConverter : ValueConverter<Currency, decimal>
{
    public CurrencyConverter()
        : base(
            v => v.Amount,
            v => new Currency(v))
    {
    }
}

然後,在您的內容類型中覆寫 ConfigureConventions ,並設定轉換器,如下所示:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder
        .Properties<Currency>()
        .HaveConversion<CurrencyConverter>();
}

預先定義的轉換

EF Core 包含許多預先定義的轉換,可避免需要手動撰寫轉換函式。 相反地,EF Core 會根據模型中的屬性類型和所要求的資料庫提供者類型,挑選要使用的轉換。

例如,列舉到字串轉換會作為上述範例使用,但 EF Core 會在提供者類型設定為 string 使用 的 HasConversion 泛型型別時自動執行這項操作:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion<string>();
}

藉由明確指定資料庫資料行類型,即可達到相同的目的。 例如,如果實體類型的定義如下:

public class Rider2
{
    public int Id { get; set; }

    [Column(TypeName = "nvarchar(24)")]
    public EquineBeast Mount { get; set; }
}

然後,列舉值將會儲存為資料庫中的字串,而不需在 中進行任何進一步的 OnModelCreating 設定。

ValueConverter 類別

如上所示呼叫 HasConversion 會建立 ValueConverter<TModel,TProvider> 實例,並在 屬性上設定它。 ValueConverter可以改為明確地建立 。 例如:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var converter = new ValueConverter<EquineBeast, string>(
        v => v.ToString(),
        v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));

    modelBuilder
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion(converter);
}

當多個屬性使用相同的轉換時,這非常有用。

內建轉換器

如上所述,EF Core 隨附一組預先定義的 ValueConverter<TModel,TProvider> 類別,可在 命名空間中找到 Microsoft.EntityFrameworkCore.Storage.ValueConversion 。 在許多情況下,EF 會根據模型中屬性的類型和資料庫中所要求的類型,選擇適當的內建轉換器,如上所示用於列舉。 例如,在 .HasConversion<int>() 屬性上使用 bool 會導致 EF Core 將布林值轉換成數值零和一個值:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<User>()
        .Property(e => e.IsActive)
        .HasConversion<int>();
}

這在功能上與建立內 BoolToZeroOneConverter<TProvider> 建的實例相同,並明確設定它:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var converter = new BoolToZeroOneConverter<int>();

    modelBuilder
        .Entity<User>()
        .Property(e => e.IsActive)
        .HasConversion(converter);
}

下表摘要說明從模型/屬性類型到資料庫提供者類型的常用預先定義轉換。 在資料表 any_numeric_type 中,表示 、 short 、、 longuintbyteushortulong 、、 sbytechar 、、 decimalfloatdoubleint 其中一個 。

模型/屬性類型 提供者/資料庫類型 轉換 使用方式
bool any_numeric_type False/true 至 0/1 .HasConversion<any_numeric_type>()
any_numeric_type 任兩個數字的 False/true 使用 BoolToTwoValuesConverter<TProvider>
string False/true 表示 「N」/「Y」 .HasConversion<string>()
string 任兩個字串的 False/true 使用 BoolToStringConverter
any_numeric_type bool 0/1 至 false/true .HasConversion<bool>()
any_numeric_type 簡單轉換 .HasConversion<any_numeric_type>()
string 數位做為字串 .HasConversion<string>()
列舉 any_numeric_type 列舉的數值 .HasConversion<any_numeric_type>()
string 列舉值的字串表示 .HasConversion<string>()
string bool 將字串剖析為 bool .HasConversion<bool>()
any_numeric_type 將字串剖析為指定的數數值型別 .HasConversion<any_numeric_type>()
char 字串的第一個字元 .HasConversion<char>()
Datetime 將字串剖析為 DateTime .HasConversion<DateTime>()
DateTimeOffset 將字串剖析為 DateTimeOffset .HasConversion<DateTimeOffset>()
TimeSpan 將字串剖析為 TimeSpan .HasConversion<TimeSpan>()
GUID 將字串剖析為 Guid .HasConversion<Guid>()
byte[] 字串為 UTF8 位元組 .HasConversion<byte[]>()
char string 單一字元字串 .HasConversion<string>()
Datetime long 編碼的日期/時間保留 DateTime.Kind .HasConversion<long>()
long 使用 DateTimeToTicksConverter
string 不因文化特性而異的日期/時間字串 .HasConversion<string>()
DateTimeOffset long 具有位移的編碼日期/時間 .HasConversion<long>()
string 具有位移的不變異文化特性日期/時間字串 .HasConversion<string>()
TimeSpan long .HasConversion<long>()
string 不因文化特性時間範圍字串而異 .HasConversion<string>()
URI string URI 做為字串 .HasConversion<string>()
PhysicalAddress string 位址做為字串 .HasConversion<string>()
byte[] 以大端網路順序排列的位元組 .HasConversion<byte[]>()
IPAddress string 位址做為字串 .HasConversion<string>()
byte[] 以大端網路順序排列的位元組 .HasConversion<byte[]>()
GUID string 'dd-d-d-d-d' 格式的 GUID .HasConversion<string>()
byte[] .NET 二進位序列化順序中的位元組 .HasConversion<byte[]>()

請注意,這些轉換假設值的格式適用于轉換。 例如,如果字串值無法剖析為數字,將字串轉換成數位將會失敗。

內建轉換器的完整清單如下:

請注意,所有內建轉換器都是無狀態的,因此單一實例可以由多個屬性安全地共用。

資料行 Facet 和對應提示

某些資料庫類型具有可修改資料儲存方式的 Facet。 包括:

  • 小數點和日期/時間資料行的有效位數和小數位數
  • 二進位和字串資料行的大小/長度
  • 字串資料行的 Unicode

這些 Facet 可以針對使用值轉換器的屬性,以一般方式設定,而且會套用至轉換的資料庫類型。 例如,從列舉轉換成字串時,我們可以指定資料庫資料行應該是非 Unicode,並儲存最多 20 個字元:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion<string>()
        .HasMaxLength(20)
        .IsUnicode(false);
}

或者,明確建立轉換器時:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var converter = new ValueConverter<EquineBeast, string>(
        v => v.ToString(),
        v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));

    modelBuilder
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion(converter)
        .HasMaxLength(20)
        .IsUnicode(false);
}

這會在針對 SQL Server 使用 EF Core 移轉時產生 varchar(20) 資料行:

CREATE TABLE [Rider] (
    [Id] int NOT NULL IDENTITY,
    [Mount] varchar(20) NOT NULL,
    CONSTRAINT [PK_Rider] PRIMARY KEY ([Id]));

不過,如果根據預設, EquineBeast 所有資料行都應該是 varchar(20) ,則可以將這項資訊提供給值轉換器做為 ConverterMappingHints 。 例如:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var converter = new ValueConverter<EquineBeast, string>(
        v => v.ToString(),
        v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v),
        new ConverterMappingHints(size: 20, unicode: false));

    modelBuilder
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion(converter);
}

現在,每當使用此轉換器時,資料庫資料行會是非 Unicode,長度上限為 20。 不過,這些只是提示,因為它們是由對應屬性上明確設定的任何 Facet 覆寫。

範例

簡單值物件

這個範例會使用簡單類型來包裝基本類型。 當您想要模型中的類型比基本類型更明確(因此更安全類型)時,這非常有用。 在此範例中,該類型為 Dollars ,它會包裝小數點基本類型:

public readonly struct Dollars
{
    public Dollars(decimal amount) 
        => Amount = amount;
        
    public decimal Amount { get; }

    public override string ToString() 
        => $"${Amount}";
}

這可用於實體類型:

public class Order
{
    public int Id { get; set; }

    public Dollars Price { get; set; }
}

當儲存在資料庫中時,會轉換成基礎 decimal

modelBuilder.Entity<Order>()
    .Property(e => e.Price)
    .HasConversion(
        v => v.Amount,
        v => new Dollars(v));

注意

這個值物件會實作為 唯讀結構 。 這表示 EF Core 可以快照集和比較值,而不會發生問題。 如需詳細資訊,請參閱 值比較子

複合值物件

在上一個範例中,value 物件類型只包含單一屬性。 實值物件類型比較常見,以組成組成定義域概念的多個屬性。 例如,包含金額和貨幣的一般 Money 類型:

public readonly struct Money
{
    [JsonConstructor]
    public Money(decimal amount, Currency currency)
    {
        Amount = amount;
        Currency = currency;
    }

    public override string ToString()
        => (Currency == Currency.UsDollars ? "$" : "£") + Amount;

    public decimal Amount { get; }
    public Currency Currency { get; }
}

public enum Currency
{
    UsDollars,
    PoundsSterling
}

這個值物件可以在實體類型中使用,如之前所示:

public class Order
{
    public int Id { get; set; }

    public Money Price { get; set; }
}

值轉換器目前只能從單一資料庫資料行來回轉換值。 這項限制表示物件中的所有屬性值都必須編碼為單一資料行值。 這通常是藉由序列化物件進入資料庫時處理,然後在出路時再次還原序列化它。例如,使用 System.Text.Json

modelBuilder.Entity<Order>()
    .Property(e => e.Price)
    .HasConversion(
        v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null),
        v => JsonSerializer.Deserialize<Money>(v, (JsonSerializerOptions)null));

注意

我們計畫在未來版本的 EF Core 中允許將物件對應到多個資料行,而不需要在這裡使用序列化。 GitHub 問題 #13947 會追蹤 此問題。

注意

如同上述範例,這個值物件會實作為 唯讀結構 。 這表示 EF Core 可以快照集和比較值,而不會發生問題。 如需詳細資訊,請參閱 值比較子

基本類型的集合

序列化也可以用來儲存基本值集合。 例如:

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Contents { get; set; }

    public ICollection<string> Tags { get; set; }
}

再次使用 System.Text.Json

modelBuilder.Entity<Post>()
    .Property(e => e.Tags)
    .HasConversion(
        v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null),
        v => JsonSerializer.Deserialize<List<string>>(v, (JsonSerializerOptions)null),
        new ValueComparer<ICollection<string>>(
            (c1, c2) => c1.SequenceEqual(c2),
            c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
            c => (ICollection<string>)c.ToList()));

ICollection<string> 表示可變動的參考型別。 這表示需要 , ValueComparer<T> 讓 EF Core 能夠正確追蹤及偵測變更。 如需詳細資訊,請參閱 值比較子

值物件的集合

將前兩個範例結合在一起,我們可以建立 value 物件的集合。 例如,請考慮建立 AnnualFinance 部落格財務模型一年的類型:

public readonly struct AnnualFinance
{
    [JsonConstructor]
    public AnnualFinance(int year, Money income, Money expenses)
    {
        Year = year;
        Income = income;
        Expenses = expenses;
    }

    public int Year { get; }
    public Money Income { get; }
    public Money Expenses { get; }
    public Money Revenue => new Money(Income.Amount - Expenses.Amount, Income.Currency);
}

此類型是由我們先前建立的數種 Money 類型所組成:

public readonly struct Money
{
    [JsonConstructor]
    public Money(decimal amount, Currency currency)
    {
        Amount = amount;
        Currency = currency;
    }

    public override string ToString()
        => (Currency == Currency.UsDollars ? "$" : "£") + Amount;

    public decimal Amount { get; }
    public Currency Currency { get; }
}

public enum Currency
{
    UsDollars,
    PoundsSterling
}

然後,我們可以將 的 AnnualFinance 集合新增至實體類型:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public IList<AnnualFinance> Finances { get; set; }
}

再次使用序列化來儲存下列專案:

modelBuilder.Entity<Blog>()
    .Property(e => e.Finances)
    .HasConversion(
        v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null),
        v => JsonSerializer.Deserialize<List<AnnualFinance>>(v, (JsonSerializerOptions)null),
        new ValueComparer<IList<AnnualFinance>>(
            (c1, c2) => c1.SequenceEqual(c2),
            c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
            c => (IList<AnnualFinance>)c.ToList()));

注意

和之前一 ValueComparer<T> 樣,此轉換需要 。 如需詳細資訊,請參閱 值比較子

將物件值為索引鍵

有時候基本索引鍵屬性可能會包裝在值物件中,以在指派值時新增額外的型別安全性層級。 例如,我們可以實作部落格的金鑰類型,以及文章的索引鍵類型:

public readonly struct BlogKey
{
    public BlogKey(int id) => Id = id;
    public int Id { get; }
}

public readonly struct PostKey
{
    public PostKey(int id) => Id = id;
    public int Id { get; }
}

然後,這些可以在領域模型中使用:

public class Blog
{
    public BlogKey Id { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts { get; set; }
}

public class Post
{
    public PostKey Id { get; set; }

    public string Title { get; set; }
    public string Content { get; set; }

    public BlogKey? BlogId { get; set; }
    public Blog Blog { get; set; }
}

請注意, Blog.Id 無法不小心指派 PostKey ,而且 Post.Id 無法不小心指派 。 BlogKey 同樣地, Post.BlogId 必須指派 BlogKey 外鍵屬性。

注意

顯示此模式並不表示我們建議使用。 請仔細考慮這種抽象概念層級是否有助於或阻礙您的開發體驗。 此外,請考慮使用導覽和產生的索引鍵,而不是直接處理索引鍵值。

然後可以使用值轉換器來對應這些索引鍵屬性:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var blogKeyConverter = new ValueConverter<BlogKey, int>(
        v => v.Id,
        v => new BlogKey(v));

    modelBuilder.Entity<Blog>().Property(e => e.Id).HasConversion(blogKeyConverter);

    modelBuilder.Entity<Post>(
        b =>
        {
            b.Property(e => e.Id).HasConversion(v => v.Id, v => new PostKey(v));
            b.Property(e => e.BlogId).HasConversion(blogKeyConverter);
        });
}

注意

具有轉換的索引鍵屬性只能使用從 EF Core 7.0 開始產生的索引鍵值。

針對 timestamp/rowversion 使用 ulong

SQL Server 支援使用 8 位元組二進位 timestamprowversion/ 資料行的自動 開放式平行存取。 這些一律會使用 8 位元組陣列從 資料庫讀取和寫入資料庫。 不過,位元組陣列是可變動的參考型別,因此處理它們會有些痛苦。 值轉換器可改為 rowversion 對應至 ulong 屬性,這比位元組陣列更合適且容易使用。 例如,請考慮 Blog 具有 ulong 並行權杖的實體:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ulong Version { get; set; }
}

這可以使用值轉換器對應至 SQL Server rowversion 資料行:

modelBuilder.Entity<Blog>()
    .Property(e => e.Version)
    .IsRowVersion()
    .HasConversion<byte[]>();

讀取日期時指定 DateTime.Kind

將 儲存 DateTimedatetimedatetime2 時, DateTime.Kind SQL Server 會捨棄 旗標。 這表示從資料庫傳回的 DateTime 值一律具有 DateTimeKindUnspecified

值轉換器可以用兩種方式來處理。 首先,EF Core 具有值轉換器,可建立 8 位元組不透明值,以保留 Kind 旗標。 例如:

modelBuilder.Entity<Post>()
    .Property(e => e.PostedOn)
    .HasConversion<long>();

這可讓資料庫中具有不同 Kind 旗標的 DateTime 值混合。

此方法的問題在於資料庫不再具有可 datetime 辨識或 datetime2 資料行。 因此,通常一律儲存 UTC 時間(或較不常見,一律是當地時間),然後使用值轉換器忽略 Kind 旗標或將它設定為適當的值。 例如,下列轉換器可確保 DateTime 從資料庫讀取的值會有 DateTimeKindUTC

modelBuilder.Entity<Post>()
    .Property(e => e.LastUpdated)
    .HasConversion(
        v => v,
        v => new DateTime(v.Ticks, DateTimeKind.Utc));

如果在實體實例中設定了本機和 UTC 值的混合,則轉換器可用來在插入之前適當地轉換。 例如:

modelBuilder.Entity<Post>()
    .Property(e => e.LastUpdated)
    .HasConversion(
        v => v.ToUniversalTime(),
        v => new DateTime(v.Ticks, DateTimeKind.Utc));

注意

請仔細考慮將所有資料庫存取碼統一為一直使用 UTC 時間,只在向使用者呈現資料時處理當地時間。

使用不區分大小寫的字串索引鍵

某些資料庫,包括 SQL Server,預設會執行不區分大小寫的字串比較。 另一方面,.NET 預設會執行區分大小寫的字串比較。 這表示,類似 「DotNet」 的外鍵值會比對 SQL Server 上的主鍵值 「dotnet」,但在 EF Core 中則不相符。 索引鍵的值比較子可用來強制 EF Core 不區分大小寫的字串比較,例如在資料庫中。 例如,請考慮使用字串索引鍵的部落格/文章模型:

public class Blog
{
    public string Id { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts { get; set; }
}

public class Post
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public string BlogId { get; set; }
    public Blog Blog { get; set; }
}

如果某些值有不同的大小寫, Post.BlogId 這將無法如預期般運作。 由此造成的錯誤將取決於應用程式正在執行的動作,但通常牽涉到未 正確修正 的物件圖形,以及/或因為 FK 值錯誤而失敗的更新。 值比較子可用來更正下列專案:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var comparer = new ValueComparer<string>(
        (l, r) => string.Equals(l, r, StringComparison.OrdinalIgnoreCase),
        v => v.ToUpper().GetHashCode(),
        v => v);

    modelBuilder.Entity<Blog>()
        .Property(e => e.Id)
        .Metadata.SetValueComparer(comparer);

    modelBuilder.Entity<Post>(
        b =>
        {
            b.Property(e => e.Id).Metadata.SetValueComparer(comparer);
            b.Property(e => e.BlogId).Metadata.SetValueComparer(comparer);
        });
}

注意

.NET 字串比較和資料庫字串比較在區分大小寫時可能不同。 此模式適用于簡單的 ASCII 金鑰,但對於具有任何特定文化特性字元的索引鍵可能會失敗。 如需詳細資訊,請參閱 定序和區分大小寫

處理固定長度的資料庫字串

上述範例不需要值轉換器。 不過,轉換器對於或 nchar(20) 之類的 char(20) 固定長度資料庫字串類型很有用。 每當值插入資料庫時,固定長度字串會填補到其完整長度。 這表示會將 「 dotnet 」 的索引鍵值從資料庫讀回為 「 dotnet.............. 」,其中 . 代表空白字元。 這樣就不會正確地與未填補的索引鍵值進行比較。

值轉換器可用來在讀取索引鍵值時修剪填補。 這可以與上一個範例中的值比較子結合,以正確比較固定長度不區分大小寫的 ASCII 索引鍵。 例如:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var converter = new ValueConverter<string, string>(
        v => v,
        v => v.Trim());
        
    var comparer = new ValueComparer<string>(
        (l, r) => string.Equals(l, r, StringComparison.OrdinalIgnoreCase),
        v => v.ToUpper().GetHashCode(),
        v => v);

    modelBuilder.Entity<Blog>()
        .Property(e => e.Id)
        .HasColumnType("char(20)")
        .HasConversion(converter, comparer);

    modelBuilder.Entity<Post>(
        b =>
        {
            b.Property(e => e.Id).HasColumnType("char(20)").HasConversion(converter, comparer);
            b.Property(e => e.BlogId).HasColumnType("char(20)").HasConversion(converter, comparer);
        });
}

加密屬性值

值轉換器可用來在將屬性值傳送至資料庫之前加密屬性值,然後在出路時將其解密。例如,使用字串反轉作為實際加密演算法的替代方式:

modelBuilder.Entity<User>().Property(e => e.Password).HasConversion(
    v => new string(v.Reverse().ToArray()),
    v => new string(v.Reverse().ToArray()));

注意

目前無法從值轉換器內取得目前 DbCoNtext 或其他會話狀態的參考。 這會限制可使用的加密類型。 投票給 GitHub 問題 #11597 ,以移除此限制。

警告

如果您擲回自己的加密來保護敏感性資料,請務必瞭解所有含意。 請考慮改用預先建置的加密機制,例如 SQL Server 上的 Always Encrypted

限制

值轉換系統目前有一些已知的限制:

  • 如上所述, null 無法轉換。 如果這是您需要的問題,請投票 ( 👍 ) 作為 GitHub 問題 #13850
  • 您無法查詢到值轉換的屬性,例如 LINQ 查詢中值轉換 .NET 類型上的參考成員。 如果這是您需要的問題,請投票給 👍 GitHub 問題 #10434 ,但請考慮改用 JSON 資料行
  • 目前無法將一個屬性的轉換分散到多個資料行,反之亦然。 如果這是您需要的問題,請投票 ( 👍 ) 作為 GitHub 問題 #13947
  • 大部分透過值轉換器對應的索引鍵不支援產生值。 如果這是您需要的問題,請投票 ( 👍 ) 作為 GitHub 問題 #11597
  • 值轉換無法參考目前的 DbCoNtext 實例。 如果這是您需要的問題,請投票 ( 👍 ) 作為 GitHub 問題 #12205
  • 使用值轉換類型的參數目前無法在原始 SQL API 中使用。 如果這是您需要的問題,請投票 ( 👍 ) 作為 GitHub 問題 #27534

未來版本會考慮移除這些限制。