【问题标题】:EF Core how to add a filter to .ThenIncludesEF Core 如何向 .ThenIncludes 添加过滤器
【发布时间】:2021-03-17 20:13:20
【问题描述】:

我使用的是 EF Core 5.0.4

我有这三个有关系的实体。

public class Parent
{
    [Key]
    public int ParentId { get; set; }
    [Key]
    public short ChildId { get; set; }
    public string ParentProp1 { get; set; }
    public string ParentProp2 { get; set; }
    public DateTime ProcessedDate { get; set; }
    public DateTime Anniversary { get; set; }

    public Child Child { get; set; }
}

public class Child
{
    public Child()
    {
        Animals = new HashSet<Animals>();
    }

    [Key]
    public short ChildId { get; set; }
    public string ChildName { get; set; }

    public virtual ICollection<Animals> Animals { get; set; }
    //UPDATED TO INCLUDE PARENT
    public Parent Parent {get;set;}
}

public class Animals
{
    [Key]
    public short AnimalId { get; set; }
    [ForeignKey("ChildId")]
    public short ChildId { get; set; }

    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public DateTime MAnniversary { get; set; }
    public DateTime PAnniversary { get; set; }

    public virtual Child Child { get; set; }
}

在我的存储库中,我试图返回父列表。如何在 IQueryable() 上添加过滤器..查看注释代码行...?

public List<Parent> Get(Request request)
{
    var data = _context.Parents
        .Include(r => r.Child)
            .ThenInclude(a => a.Animals)
        .AsQueryable().AsNoTracking();

    data = data.Where(x => x.ProcessedDate == request.ProcessedDate);

    // Here is the filter I'm trying to add but can't because data is an IQueryable() :
    // Animals needs to be filtered based off a query like:
    // data.Child.Animals = data.Child.Animals.Where( d => d.StartDate <= data.ProcessedDate && (
    //                        d.EndDate == null || data.ProcessDate <= d.EndDate
    //                       )
    //                       && d.ChildId == data.ChildId && data.Anniversary >= d.MAnniversary
    //                       ).ToList();

    return data;
}

当只返回 Parent 时,我可以像下面这样添加过滤器查询而不会出现任何问题,因为 'data' 不是 IQueryable() :

public Parent Get(int id)
{
    var data = _context.Parents
        .Include(r => r.Child)
            .ThenInclude(a => a.Animals)
        .FirstOrDefault(x => x.ParentId == id);

    data = data.Where(x => x.ProcessedDate == request.ProcessedDate);

    data.Child.Animals = data.Child.Animals.Where(d => d.StartDate <= data.ProcessedDate && (
                            d.EndDate == null || data.ProcessDate <= d.EndDate
                           )
                           && d.ChildId == data.ChildId && data.Anniversary >= d.MAnniversary
                            ).ToList();
    return data;
}

我尝试在 .ThenInlude() 上添加一个过滤器,如下所示,但它不起作用,因为我无法访问所需的属性。

var data = _context.Parents
            .Include(r => r.Child)
                .ThenInclude(a => a.Animals.Where(x => x.StartDate <= "this doesn't work because can't access Parent or Child properties")
            .AsQueryable().AsNoTracking();

更新

我将导航父导航属性添加到子级,并将查询更改为基于内部关系。它看起来像这样:

var data = _context.Animals
        .Include(r => r.Child)
            .ThenInclude(a => a.Parent)
        .Where(r => r.StartDate <= r.Child.Parent.ProcessedDate && (
                            r.EndDate == null || r.Child.Parent.ProcessDate <= r.EndDate
                           )
                           && r.ChildId == r.Child.Parent.ChildId && 
                 r.Child.Parent.Anniversary >= r.MAnniversary
               ).AsQueryable().AsNoTracking();

【问题讨论】:

  • 您使用的是 .net 5 吗?使用 EF Core 5?因为那是在 .net 5 中添加的,我相信
  • @MiltoxBeyond 我正在使用 EF Core 5.0.4 和 dotnet Core 3.1.0。
  • 你想做什么?请描述您需要什么。
  • @zolty13 我想将“data.Child.Animals.Where(..)”过滤器添加到 AsQueryable()。
  • 基于内部关系的查询呢?喜欢:_context.Children.Include(c =&gt; c.Animals.Where(a =&gt; /*condition*/ )) .include(c=&gt;c.Parent).where(c=&gt;c.Animals.Count()&gt;0)

标签: c# linq entity-framework-core asqueryable


【解决方案1】:

我将 Parent 导航属性添加到 Child 并将查询更改为基于内部关系。它看起来像这样:

var data = _context.Animals
        .Include(r => r.Child)
            .ThenInclude(a => a.Parent)
        .Where(r => r.StartDate <= r.Child.Parent.ProcessedDate && (
                            r.EndDate == null || r.Child.Parent.ProcessDate <= r.EndDate
                           )
                           && r.ChildId == r.Child.Parent.ChildId && 
                 r.Child.Parent.Anniversary >= r.MAnniversary
               ).AsQueryable().AsNoTracking();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-29
    • 2021-10-01
    • 1970-01-01
    • 2021-04-24
    • 2021-04-21
    • 2018-03-14
    • 2018-09-03
    • 1970-01-01
    相关资源
    最近更新 更多