【问题标题】:Can null check cause client side evaluation?空检查会导致客户端评估吗?
【发布时间】:2019-04-04 08:27:57
【问题描述】:

我想问一下为什么要在客户端评估这样的查询:

_context
    .Items
    .Include(x => x.Status)

    .Include(x => x.Orders)
    .ThenInclude(x => x.User)

    .Include(x => x.Orders)
    .ThenInclude(x => x.OrderStatus)

    .Where(x => x.Orders.Any())
    .Where(x => x.Order != null)
    .Where(x => x.Order.User.SomeProperty.ToLower() == user.SomeProperty.ToLower());

user.SomeProperty.ToLower() 中使用的用户只是身份用户,它不为空。

public class Item
{
    public Guid Id = { get; protected set; }

    public List<Order> Orders { get; set; } = new List<Order>();

    public Order Order => Orders.FirstOrDefault(x => x.OrderStatus.Name = "Active");

    public Status Status { get; set; }
}

public class Order
{
    public Guid Id = { get; protected set; }

    public User User = { get; set; }

    public Status OrderStatus = { get; set; }
}

public class Status
{
    public Guid Id = { get; protected set; }

    public string Name = { get; set; }
}

EF Core 警告说空检查是原因之一,但我不明白为什么不能翻译空检查

警告:Microsoft.EntityFrameworkCore.Query[20500] LINQ 表达式 'where (Property([x].Order, "Id") != null)' 无法翻译,将在本地计算。

警告:Microsoft.EntityFrameworkCore.Query[20500] 无法翻译 LINQ 表达式“where ([x].Order.User.SomeProperty==__user_SomeProperty_0)”,将在本地进行计算。

【问题讨论】:

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


    【解决方案1】:

    EF 无法翻译方法或属性中的查询。移动这个

    public Order Order => Orders.FirstOrDefault(x => x.OrderStatus.Name = "Active");
    

    到实际查询

    编辑。您可以使用扩展方法来重用查询

    edit2:创建扩展方法

    public static class FooQueryExtensions
    {
       public static IQueryable<FooResult> MyFooQuery(this IQueryable<Foo> source)
       {
          return source.SelectMany(...).Where(...); //basicly do what yuo want
       }
    }
    

    习惯了

    _context.Set<Foo>().MyFooQuery().Where(result => more query);
    

    【讨论】:

    • 所以,我得在.Where(x =&gt; x.Order != null)之前执行.ToList()?
    • 这是一种解决方案,但如果您有很多物品,它可能会非常昂贵。我会编写一个采用正确 IQueryable 的扩展方法
    • 我可以将该 Func 移动到一个地方并在 Orders.cs (public Order Order =&gt; Orders.FirstOrDefault(x =&gt; x.OrderStatus.Name = "Active");) 和数据库查询中都使用它吗?或者这是不可能的
    • 是的,您可以将其移至采用 IQueryable 并返回 IQueryable 的扩展方法
    • 我的意思是,用它作为属性定义public Order Order =&gt; MyMethodThatReturnsIQueryable();?
    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 2013-06-21
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    相关资源
    最近更新 更多