Entity Framework сгруппировать по включенной таблице - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть две таблицы, объединенные 1-n способом.

Первая таблица - Пользователи :

enter image description here

Вторая таблица - Согласие :

enter image description here

В SQL Сервер я использую этот запрос

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

для достижения этой цели

enter image description here

В моем. 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; }
}

Как я могу получить тот же результат запроса через Entity Framework? Так что только самое последнее согласие по типу для каждого пользователя.

Я использую эту лямбду, чтобы получить пользователя, как я могу изменить ее, чтобы получить желаемый результат?

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

Спасибо!

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

После нескольких тестов и нескольких исследований мне удалось решить с помощью сложной лямбды.

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();
0 голосов
/ 23 апреля 2020

Здесь я использовал LINQ вместо лямбда-выражений, потому что в этом сценарии иногда лямбда может быть хитрой, я также использовал явное соединение, поэтому объяснение стало легче понять.

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();
...