在 .NET 中使用 Entity Framework Core 时,如何重用Where调用中的逻辑?

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

我正在 .NET 中使用 LINQ 编写数据库查询,并且我希望能够不重复我在

Where
方法调用中放入的代码。我的所有实体都继承
BaseEntity
并具有在
Where
调用中使用的共同属性。

public class BaseEntity
{
    public Guid Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
    public DateTime? DeletedAt { get; set; }
}
public class A : BaseEntity
{
    public List<B> Bs { get; set; }
}

public class B : BaseEntity
{
    public A A { get; set; }
}

目前我已经编写了一个有效的查询,但我不满意需要重复代码。看起来像这样:

var result = _context.Set<A>().Include(a => a.Bs.Where(b => b.DeletedAt == null && b.UpdatedAt > dateTime ||
                                                            b.DeletedAt != null && b.DeletedAt > dateTime))
                              .Where(a => a.DeletedAt == null && a.UpdatedAt > dateTime ||
                                          a.DeletedAt != null && a.DeletedAt > dateTime)
                              .ToList();

正如您所看到的

Where
调用中的代码几乎相同,但我找不到一种方法将其放在某个位置并能够重用它。我确实尝试为
IQueryable
创建扩展,但我无法在
Where
内的
Include
中使用它,因为
Bs
不是
IQueryable
。 显然,仅仅将逻辑放入方法中是行不通的,因为它无法被翻译。

c# .net linq entity-framework-core iqueryable
1个回答
0
投票

一个常见的表达方式应该有效,但它可能没有正确实现,因为它们可能有点喜怒无常。例如:

private Expression<Func<T, bool>> FilterByDate<T>(DateTime dateTime) where T : BaseEntity
{
    Expression<Func<T, bool>> expression = x => 
        (x.DeletedAt == null && x.UpdatedAt > dateTime) 
        || (x.DeletedAt != null && x.DeletedAt > dateTime)
    return expression;
}

然后在您的查询中:

var result = _context.Set<A>().Include(a => a.Bs.Where(filterByDate<B>(dateTime))
    .Where(a => filterByDate<A>(dateTime))
    .ToList();

我使用日期基类运行的测试看起来适用于项目和包含的子项的过滤。它确实需要显式地向过滤器调用提供类型。

© www.soinside.com 2019 - 2024. All rights reserved.