获取最新的子记录-EF Core

时间:2018-12-19 03:57:06

标签: c# linq entity-framework-core

Users与另一个表有一些关系

这是代码段

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit)
                .ThenInclude(x => x.FormLevel)
           .Where(x => true);

所以现在,我需要来自FormSubmit的最新记录。所以我修改了查询,如下所示:

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit.OrderByDescending(i => i.CreationDate).Take(1))
                .ThenInclude(x => x.FormLevel)
           .Where(x => true);

但是我有一个例外:

"Message": "The Include property lambda expression 'x => {from FormSubmit i in x.FormSubmit orderby [i].CreationDate desc select [i] => Take(1)}' is invalid. The expression should represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, specify an explicitly typed lambda parameter of the target type, E.g. '(Derived d) => d.MyProperty'. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393."

是否知道如何从FormSubmit获取最新记录?

2 个答案:

答案 0 :(得分:2)

到目前为止,您无法直接实现它,因为EF Core中的紧急加载或延迟加载都不支持子集合中的排序或过滤。

由于您的要求不清楚,因此我正在为所有可能的情况提供可能的替代解决方案:

1)如果您想要某个用户的最新FormSubmit

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit)
                .ThenInclude(x => x.FormLevel)
           .Where(x => true && x.UserId == userId).FirstOrDefault();

var latestFormSubmit = users.Select(u => u.FormSubmit).OrderByDescending(fs => fs.CreationDate).FirstOrDefault();

2)如果要在所有用户中最晚FormSubmit

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit)
                .ThenInclude(x => x.FormLevel)
           .Where(x => true).ToList();

var latestFormSubmit = users.SelectMany(u => u.FormSubmit).OrderByDescending(fs => fs.CreationDate).FirstOrDefault();

    //Or

var latestFormSubmit = DbContext.FormSubmits.Include(x => x.FormLevel).OrderByDescending(fs => fs.CreationDate).FirstOrDefault();

注意:如果只需要最新的.Include(x => x.ApplicationUserGroups).ThenInclude(x => x.ApplicationGroup),则可以从查询中省略FormSubmit

答案 1 :(得分:0)

导航属性(如您的User.FormSubmit属性)旨在容纳 all 个相关实体(如果未加载,则不包含任何实体)。

您根本不能那样使用Include()Include()仅用于检索 all 相关记录。

如果只需要一个相关记录,则需要单独进行。例如:

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Where(x => true);

foreach (var user in users) {
    var latest = DbContext.FormSubmits.Include(s => s.FormLevel).Where(s => s.UserId == user.UserId).OrderByDescending(i => i.CreationDate).FirstOrDefault()
    //Do other stuff...
}

以此方式将检索每个用户的最新帖子。如果您在第一个查询中执行.Include(x => x.FormSubmit).ThenInclude(x => x.FormLevel),然后进行过滤,最终将为每个用户 all 个提交,这比您实际使用的数据要多。