EntityFramework 在Where 子句中使用自己的逻辑而不是方法

问题描述 投票:0回答:1

在使用 EntityFramework 的 C# 项目中使用

Compare
时,我偶然发现了一个有趣的行为。

当使用具有签名

Compare(byte[], byte[])
的方法时,EntityFramework 不使用此方法,而是在 SQL 查询中进行比较。 我的期望是它应该在本地进行评估(并根据配置抛出异常)

public class MyEntity
{
  ...

  [Required]
  [ConcurrencyCheck]
  public byte[] Timestamp { get; set; }
}


public static int Compare(this byte[] left, byte[] right)
{
  throw new InvalidOperationException("...");
}

byte[] someValue = ...;
MyEntity[] items = context.MyEntities
    .Where(e => e.Timestamp.Compare(someValue) <= 0)
    .ToArray();

此代码不会抛出异常,但会生成如下 SQL 查询:

SELECT .....
FROM [MyEntities] AS [f]
WHERE [f].[Timestamp] <= @__someValue_0

重命名该方法时,该方法不再起作用,并且会引发预期的异常。

在不使用扩展方法的情况下直接使用它时,这也适用。

public static class MyExtensions
{
  public static int Compare(byte[] left, byte[] right)
  {
    throw new InvalidOperationException("...");
  }
}

byte[] someValue = ...;
MyEntity[] items = context.MyEntities
    .Where(e => MyExtensions.Compare(e.Timestamp, someValue) <= 0)
    .ToArray();

造成这种行为的原因是什么?有相关文档吗?

c# entity-framework entity-framework-core
1个回答
0
投票

这就是当前 EF Core 提供翻译的方式:

如果您点击此链接,您会发现 EF Core 会转换具有类似签名的任何

Compare
CompareTo
方法。

if (method.ReturnType == typeof(int))
{
    SqlExpression? left = null;
    SqlExpression? right = null;
    if (method.Name == nameof(string.Compare)
        && arguments.Count == 2
        && arguments[0].Type == arguments[1].Type)
    {
        left = arguments[0];
        right = arguments[1];
    }
    else if (method.Name == nameof(string.CompareTo)
                && arguments.Count == 1
                && instance != null
                && instance.Type == arguments[0].Type)
    {
        left = instance;
        right = arguments[0];
    }
    ...
© www.soinside.com 2019 - 2024. All rights reserved.