linq to sql сделать простую группу в конце - PullRequest
0 голосов
/ 08 января 2020

У меня есть этот linq

(from a in Customers
join b in CustomerContacts.Where(p => p.Contact.ContactType.Code == "phone") on a.Id equals b.CustomerId into bb
from b in bb.DefaultIfEmpty()
join e in CustomerContacts.Where(p => p.Contact.ContactType.Code == "email") on a.Id equals e.CustomerId into ee
from e in ee.DefaultIfEmpty()
join f in Bookings.Where(p => p.EntityId == 4) on a.Id equals f.CustomerId into ff
from f in ff.DefaultIfEmpty()
join h in CustomerAddresses on a.Id equals h.CustomerId into hh
from h in hh.DefaultIfEmpty()
where
    (b.Contact.Value.Contains("123") || e.Contact.Value.Contains("123"))
    && (a.EntityId == 4 || f != null)
select new {
    a.Id,
    phone = b.Contact.Value,
    email = e.Contact.Value,
    count = Vehicles.Where(p => p.CustomerId == a.Id).Count(),
    h.Address.State,
    h.Address.Suburb
}
)

Он переведен в sql (mysql)

SELECT `a`.`Id`, `b.Contact`.`Value` AS `phone`, `e.Contact`.`Value` AS `email`, (
    SELECT COUNT(*)
    FROM `Vehicle` AS `p2`
    WHERE `p2`.`CustomerId` = `a`.`Id`
) AS `count`, `h.Address`.`State`, `h.Address`.`Suburb`
FROM `Customer` AS `a`
LEFT JOIN (
    SELECT `p`.*
    FROM `CustomerContact` AS `p`
    INNER JOIN `Contact` AS `p.Contact` ON `p`.`ContactId` = `p.Contact`.`Id`
    INNER JOIN `ContactType` AS `p.Contact.ContactType` ON `p.Contact`.`ContactTypeId` = `p.Contact.ContactType`.`Id`
    WHERE `p.Contact.ContactType`.`Code` = 'phone'
) AS `t` ON `a`.`Id` = `t`.`CustomerId`
LEFT JOIN `Contact` AS `b.Contact` ON `t`.`ContactId` = `b.Contact`.`Id`
LEFT JOIN (
    SELECT `p0`.*
    FROM `CustomerContact` AS `p0`
    INNER JOIN `Contact` AS `p.Contact0` ON `p0`.`ContactId` = `p.Contact0`.`Id`
    INNER JOIN `ContactType` AS `p.Contact.ContactType0` ON `p.Contact0`.`ContactTypeId` = `p.Contact.ContactType0`.`Id`
    WHERE `p.Contact.ContactType0`.`Code` = 'email'
) AS `t0` ON `a`.`Id` = `t0`.`CustomerId`
LEFT JOIN `Contact` AS `e.Contact` ON `t0`.`ContactId` = `e.Contact`.`Id`
LEFT JOIN (
    SELECT `p1`.*
    FROM `Booking` AS `p1`
    WHERE `p1`.`EntityId` = 4
) AS `t1` ON `a`.`Id` = `t1`.`CustomerId`
LEFT JOIN `CustomerAddress` AS `h` ON `a`.`Id` = `h`.`CustomerId`
LEFT JOIN `Address` AS `h.Address` ON `h`.`AddressId` = `h.Address`.`Id`
WHERE ((LOCATE('123', `b.Contact`.`Value`) > 0) OR (LOCATE('123', `e.Contact`.`Value`) > 0)) AND ((`a`.`EntityId` = 4) OR `t1`.`Id` IS NOT NULL)

и результат

enter image description here

однако он содержит дублированный идентификатор, я хочу добавить group by a.Id в конце, чтобы удалить дублированный идентификатор. Пробовал с группой, но она не может достичь чего-то подобного

SELECT `a`.`Id`, `b.Contact`.`Value` AS `phone`, `e.Contact`.`Value` AS `email`, (
    SELECT COUNT(*)
    FROM `Vehicle` AS `p2`
    WHERE `p2`.`CustomerId` = `a`.`Id`
) AS `count`, `h.Address`.`State`, `h.Address`.`Suburb`
FROM `Customer` AS `a`
LEFT JOIN (
    SELECT `p`.*
    FROM `CustomerContact` AS `p`
    INNER JOIN `Contact` AS `p.Contact` ON `p`.`ContactId` = `p.Contact`.`Id`
    INNER JOIN `ContactType` AS `p.Contact.ContactType` ON `p.Contact`.`ContactTypeId` = `p.Contact.ContactType`.`Id`
    WHERE `p.Contact.ContactType`.`Code` = 'phone'
) AS `t` ON `a`.`Id` = `t`.`CustomerId`
LEFT JOIN `Contact` AS `b.Contact` ON `t`.`ContactId` = `b.Contact`.`Id`
LEFT JOIN (
    SELECT `p0`.*
    FROM `CustomerContact` AS `p0`
    INNER JOIN `Contact` AS `p.Contact0` ON `p0`.`ContactId` = `p.Contact0`.`Id`
    INNER JOIN `ContactType` AS `p.Contact.ContactType0` ON `p.Contact0`.`ContactTypeId` = `p.Contact.ContactType0`.`Id`
    WHERE `p.Contact.ContactType0`.`Code` = 'email'
) AS `t0` ON `a`.`Id` = `t0`.`CustomerId`
LEFT JOIN `Contact` AS `e.Contact` ON `t0`.`ContactId` = `e.Contact`.`Id`
LEFT JOIN (
    SELECT `p1`.*
    FROM `Booking` AS `p1`
    WHERE `p1`.`EntityId` = 4
) AS `t1` ON `a`.`Id` = `t1`.`CustomerId`
LEFT JOIN `CustomerAddress` AS `h` ON `a`.`Id` = `h`.`CustomerId`
LEFT JOIN `Address` AS `h.Address` ON `h`.`AddressId` = `h.Address`.`Id`
WHERE ((LOCATE('123', `b.Contact`.`Value`) > 0) OR (LOCATE('123', `e.Contact`.`Value`) > 0)) AND ((`a`.`EntityId` = 4) OR `t1`.`Id` IS NOT NULL)
Group by `a`.`Id`

1 Ответ

0 голосов
/ 09 января 2020

Вы пробовали что-то подобное?

(from a in Customers
join b in CustomerContacts.Where(p => p.Contact.ContactType.Code == "phone") on a.Id equals b.CustomerId into bb
from b in bb.DefaultIfEmpty()
join e in CustomerContacts.Where(p => p.Contact.ContactType.Code == "email") on a.Id equals e.CustomerId into ee
from e in ee.DefaultIfEmpty()
join f in Bookings.Where(p => p.EntityId == 4) on a.Id equals f.CustomerId into ff
from f in ff.DefaultIfEmpty()
join h in CustomerAddresses on a.Id equals h.CustomerId into hh
from h in hh.DefaultIfEmpty()
where
    (b.Contact.Value.Contains("123") || e.Contact.Value.Contains("123"))
    && (a.EntityId == 4 || f != null)
select new {
    a.Id,
    phone = b.Contact.Value,
    email = e.Contact.Value,
    count = Vehicles.Where(p => p.CustomerId == a.Id).Count(),
    h.Address.State,
    h.Address.Suburb
}).GroupBy(i => i.Id).ToList();
...