【问题标题】:Entity Framework group by on the included table包含表上的实体框架分组
【发布时间】:2020-04-23 14:35:17
【问题描述】:

我有两个表以 1-n 方式连接。

第一个表 - 用户

第二张表 - 同意

在 SQL Server 中我使用这个查询

SELECT *
FROM Users
  Inner Join (
    Select Consent.IDUser, Consent.Type, Consent.Date, Consent.Consent
    From Consent
    Inner Join (
        Select IDUser, Type, Max(Date) as MaxDate
        From Consent
        Group By IDUser, Type
    ) As ConsentGrouped on Consent.IDUser = ConsentGrouped.IDUser and Consent.Type = ConsentGrouped.Type and Consent.Date = ConsentGrouped.MaxDate
  ) as AllData
  On Users.id = AllData.IDUser

实现这一目标

在我的 .NET 项目中,我使用实体框架,所以我有这两个实体:

    public partial class Users
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Users()
        {
            this.Consent = new HashSet<Consent>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Consent> Consent{ get; set; }
    }

public partial class Consent
{
    public int Id { get; set; }
    public Nullable<int> IDUser { get; set; }
    public string Type { get; set; }
    public string Origin { get; set; }
    public Nullable<System.DateTime> Date { get; set; }
    public Nullable<bool> Consent { get; set; }

    public virtual Users Users { get; set; }
}

如何通过实体框架获得相同的查询结果?因此,只有每个用户的最新同意类型。

我使用这个 lambda 获取用户,如何修改它以获得想要的结果?

 var user = await db.Users
     .Include(ut => ut.Consent)
     .Where(ut => ut.Id == userID)
     .FirstOrDefaultAsync();

谢谢!

【问题讨论】:

    标签: c# .net entity-framework group-by sql-order-by


    【解决方案1】:

    这里我使用了 LINQ 而不是 lambda 表达式,因为在这种情况下 lambda 有时会很棘手,我还使用了显式连接,这样解释就更容易理解了。

    var query = (from user in users
                        join consent in consents
                            on user.Id equals consent.IdUser
                        group new {user, consent} by new {consent.Type, consent.IdUser} into g 
                        select new { 
                                g.FirstOrDefault().user.Id, 
                                g.FirstOrDefault().user.Name,
                                g.FirstOrDefault().user.SureName,
                                ConsentId = g.FirstOrDefault().consent.Id,
                                g.FirstOrDefault().consent.IdUser,
                                g.FirstOrDefault().consent.Type,
                                g.FirstOrDefault().consent.Origin,
                                Date = g.Max(m => m.consent.Date),
                                g.FirstOrDefault().consent.ConsentFlag
                            }).ToList();
    

    【讨论】:

    • 安德烈,感谢您的支持。我试过你的查询,它在 sql server 中准确地返回了查询结果。我无法修改它以逐个获取结构化类,因为我发布的 lambda 返回。但是,如果您想看一下,我找到了不同的解决方案。谢谢!
    • 你好,卢西亚诺!需要的输出是什么?在你的回答中查看我的评论:)
    【解决方案2】:

    经过一些测试和研究,我设法使用复杂的 lambda 解决了问题。

    var user = db.Users
        .Where(ut => ut.Id == userID)
        .Select(b => new UsersResource
            {
                Id = b.Id,
                Name = b.Name,
                Surname = b.Surname,
                Consent = b.Consent
                .GroupBy(item => item.Type,
                    (key, g) => g.OrderByDescending(gx => gx.Date).FirstOrDefault())
                .Select(st => new ConsentResource
                    {
                        Id = st.Id,
                        IDUser = st.IDUser,
                        Type = st.Type,
                        Origin = st.Origin,
                        Date = st.Date,
                        Consent = st.Consent
                    }).ToList()
                 }).FirstOrDefault();
    

    【讨论】:

    • 很棒的解决方案,卢西亚诺。我相信您可以使用 FirstOrDefault 而不是 ToList() 因为选择结果只是您所说的一个
    • 你是对的!我放了 ToList 是因为 FirstOrDefault 给了我一个错误,但现在它工作得很好(我很困惑,可能错误必须在 lambda 的其他地方)。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-08-10
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    相关资源
    最近更新 更多