【问题标题】:ef core linq filtered child entitiesef core linq 过滤的子实体
【发布时间】:2017-08-26 05:21:08
【问题描述】:

我的 linq 查询有问题。 我有 3 个实体: 用户、目标和结果。 每个用户可以有多个(或没有)目标,每个目标可以有多个(或没有)结果 我想要一个返回所有用户的查询,包括可能的目标和可能的结果。这很好用。但现在我想包含过滤器来过滤目标和结果。这样查询只返回符合这些条件的用户、目标和结果。

public class User
{
  public ICollection Targets {get;set;}
  public string otherProperty {get;set;}
}

public class Target
{
  public ICollection Results {get;set;}
  public User user {get;set;}
  public string Language {get;set;}
}

public class Result
{
  public Target Target {get;set;}
  public int score {get;set;}
}

任何 EF 核心 linq 专家可以帮助我吗?

亲切的问候, 罗布雷希特

编辑 1

var query =
from auditUser in _auditUserRepository.GetAll().Include(u => u.user)
.WhereIf(!input.Group.IsNullOrWhiteSpace(), u => u.Group == input.Group)
.WhereIf(!input.Filter.IsNullOrWhiteSpace(), u => u.user.FullName.ToLower().Contains(input.Filter.ToLower()))
select auditUser;

var results = query
.Include(u => u.Targets)
.ThenInclude(t => t.AuditResults)
.PageBy(input)
.ToListAsync();

await query
.SelectMany(u => u.Targets)
.WhereIf(!input.Language.IsNullOrWhiteSpace(), t => t.Target == input.Language)
.SelectMany(t => t.AuditResults)
.WhereIf(input.From != null, r => r.CompletionDate >= input.From)
.WhereIf(input.To != null, r => r.CompletionDate <= input.From)
.LoadAsync();

这就是我想要的,但它有两个问题:

  1. 当 a 没有结果时,不包括目标。似乎它 include 或 theninclude 创建内部联接而不是左联接。
  2. 这不会过滤语言或日期。

【问题讨论】:

  • 你能显示你当前的查询和一些示例过滤条件吗?
  • 如果您的意思是过滤的包含,它们在 EF 中从未得到支持,现在仍然不支持(包括最新的 EF Core 2.0)。解决方案是投影(select)查询。
  • 嗨,Ivan,你能举个投影查询的例子吗?

标签: c# entity-framework linq


【解决方案1】:

我建议您创建一个具有所需属性的 ViewModel 类。示例:

public class UserViewModel
    {
    [Display(Name = "Other")]
    public string otherProperty {get; set;}
    [Display(Name = "Possible Targets")]
    public List<Target> targets {get; set;}
    [Display(Name = "Possible Results")]
    public List<Result> results{get; set;}
    }

然后在您的“存储库”类中,您可以创建一个过滤结果的方法。

public List<UserViewModel> GetUserViewModelBy(int scoreFilter, string filter1= "", string filter2)
        {
            IQueryable<Result> query = _context.Results.Where(i => i.score==scoreFilter)).Include(x => x.Target)
                                                               .Include(x => x.Target.Results.ToList())
                                                               .Include(x => x.User)
.Include(x=>x.User.Targets.Where(i=>i.Language.ToLower().Contains(filter1)).ToList());

            if (!string.IsNullOrEmpty(filter2))
            {
                query = query.Where(x => x.Target.Language.ToLower().Contains(filter2));
            }

            return query.Select(x => new UserViewModel()
            {
                otherProperty = x.User.otherProperty,
                targets = x.User.targets,
                results = x.Results

            }).ToList();
        }

【讨论】:

  • 如果分数过滤器是可选的,过滤器的外观如何。当它不存在时,我希望所有用户和目标也有结果。
猜你喜欢
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
相关资源
最近更新 更多