【问题标题】:Is it possible to use EF Function Translation during an Add in Entity Framework 5?是否可以在添加实体框架 5 期间使用 EF 函数转换?
【发布时间】:2021-09-06 09:56:19
【问题描述】:

长话短说,过去几天我们一直在创建翻译,以将密钥解密/加密添加到实体框架中。

以下选择有效(硬编码键“test”仅用于测试环境,稍后将与密钥库一起存储) EF.Functions.Decrypt 触发一个翻译表达式,它为实体框架编写自定义 SQL 以利用内部解密方法。

var filteredSet = Set.Include(x => x.Table2)
            .Where(x => x.Id == id)
            .Where(x => x.Table2.IsSomething)
            .Select(m => new Model
        {
            Id = m.Id,
            Decrypted = EF.Functions.Decrypt("test", m.Encrypted), //string
            Table2 = m.Table2,
            Encrypted = m.Encrypted //byte[]
        }).ToList();

以下内容(正如我所预料的那样)没有。

public Model createNew(string Data)
    {
        Set.Add(
                new Model
                {
                    Encrypted = EF.Functions.Encrypt("test", Data)
                }
            );
        return new Model();
    }

当以这种方式使用时,它会尝试使用 EF 函数创建新模型对象并抛出 InvalidOperationError。 有没有办法在 EF 中执行 Add in 来转换此函数,而不是尝试将代码执行到模型中?

【问题讨论】:

  • 无法通过 EF Core 的更改跟踪器实现。只能通过第三方扩展。
  • 你知道任何扩展吗?或有关他们如何完成它的任何文档?
  • 问题是在创建/更新/删除实体时不涉及表达式,而EF.Functions 只是在表达式中有意义的函数调用的占位符。外部表达式他们没有实现。正如 Svyaloslav 所指出的,EF 的变更跟踪器无法处理它,它只能处理设定值。也就是说,我喜欢这里的开箱即用的想法。我认为 EF可以提供一个 API 用于将函数注入 CUD 查询,但问题是他们是否会在这样的功能中看到足够的附加值。

标签: c# reflection entity-framework-core asp.net-core-mvc translation


【解决方案1】:

由于目前没有将表达式树传递给 EF Core ChangeTracker 的解决方案,您可以尝试linq2db.EntityFrameworkCore

加密扩展方法:

public static class SqlFunctions
{
    [Sql.Function("DECRYPTBYPASSPHRASE", ServerSideOnly = true)]
    public static string DecryptByPassPhrase(string passphrase, byte[]? ciphertext) 
        => throw new NotImplementedException();

    [Sql.Function("ENCRYPTBYPASSPHRASE", ServerSideOnly = true)]
    public static byte[]? EncryptByPassPhrase(string passphrase, string? cleartext) 
        => throw new NotImplementedException();

}

以及基本的 CRUD 操作:

选择

var filteredSet = Set
    .Where(x => x.Id == id)
    .Where(x => x.Table2.IsSomething)
    .Select(m => new Model
    {
        Id = m.Id,
        Decrypted = SqlFunctions.DecryptByPassPhrase("test", m.Encrypted), //string
        Table2 = m.Table2,
        Encrypted = m.Encrypted //byte[]
    })
    .ToLinqToDB()
    .ToList();

插入

Set.ToLinqToDBTable()
    .Insert(() => new Model
    {
        Encrypted = SqlFunctions.EncryptByPassPhrase("test", Data)
    })

更新

Set
    .Where(x => x.Id == id)
    .Set(x => s.Encrypted, x => SqlFunctions.EncryptByPassPhrase("test", Data))
    .Update();

【讨论】:

    猜你喜欢
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多