Вот подход к решению вашего вопроса.
Для начала давайте объединим 5 таблиц. Хитрость здесь в том, чтобы LEFT JOIN
из таблицы hleaves
проверить, перекрывает ли интервал отпуска с фильтруемой неделей; классический способ заключается в использовании выражения вроде: l.dateStart < @weekEnd AND l.dateEnd < @weekStart
:
SELECT *
FROM
users u
INNER JOIN teams t ON t.team_id = u.link_team_id
INNER JOIN hreg r ON r.hreg_id = u.link_hreg_id
LEFT JOIN hleave l ON l.user = u.user_id AND l.dateStart < @weekEnd AND l.dateEnd < @weekStart
LEFT JOIN leave_codes lc ON lc.code_id = l.leaveCode
Имея этот набор данных, мы можем теперь использовать условное агрегирование для получения желаемых результатов. Например, чтобы проверить статус во вторник, мы должны сделать:
MAX(
CASE
-- employee on leave
WHEN DATE_ADD(@weekStart, INTERVAL 1 DAY) BETWEEN l.dateStart AND l.dateEnd THEN lc.codeName
-- employee on schedule for that day
WHEN 2 BETWEEN h.weekStart AND h.weekEnd THEN 'working'
-- employee not on schedule for that day
ELSE 'not working'
END
) AS Tuesday
Вы можете повторять это выражение для каждого дня недели, увеличивая счетчики. Вот запрос с понедельника по среду:
SELECT
u.firstName,
MAX(
CASE
WHEN @weekStart BETWEEN l.dateStart AND l.dateEnd THEN lc.codeName
WHEN 2 BETWEEN h.weekStart AND h.weekEnd THEN 'working'
ELSE 'not working'
END
) AS Monday,
MAX(
CASE
WHEN DATE_ADD(@weekStart, INTERVAL 1 DAY) BETWEEN l.dateStart AND l.dateEnd THEN lc.codeName
WHEN 2 BETWEEN h.weekStart AND h.weekEnd THEN 'working'
ELSE 'not working'
END
) AS Tuesday,
MAX(
CASE
WHEN DATE_ADD(@weekStart, INTERVAL 2 DAY) BETWEEN l.dateStart AND l.dateEnd THEN lc.codeName
WHEN 3 BETWEEN h.weekStart AND h.weekEnd THEN 'working'
ELSE 'not working'
END
) AS Wednesday
-- other days go here
FROM
users u
INNER JOIN teams t ON t.team_id = u.link_team_id
INNER JOIN hreg r ON r.hreg_id = u.link_hreg_id
LEFT JOIN hleave l ON l.user = u.user_id AND l.dateStart < @weekEnd AND l.dateEnd < @weekStart
LEFT JOIN leave_codes lc ON lc.code_id = l.leaveCode
GROUP BY
u.user_id,
u.firstName
Ваш пример делает не реализация IFoo и неявно и явно. Вы только реализуете IFoo. DoSometing () явно. У Вас есть новый метод на Вашем классе под названием DoSomething (). Это не имеет никакого отношения к IFoo. DoSomething, за исключением того, что это имеет то же имя и параметры.
Каждый класс, который реализует интерфейс, имеет отображение между участниками того класса и участниками интерфейса. Если класс явно реализации интерфейсный участник, то явная реализация будет всегда , отображается на интерфейсе. Если не будет явной реализации тогда ожидается, то неявная реализация, и что каждый будет отображен на интерфейсе.
, Когда класс имеет то же имя элемента и связанные типы как интерфейс , но это также явно реализует члена-корреспондента для интерфейса, тогда "неявная" реализация класса не , рассмотрел реализацию интерфейса во всем (если явная реализация не называет его).
В дополнение к различным значениям в каждом случае, где класс реализует несколько интерфейсов с тем же именем элемента / типы, даже только с одним интерфейсом, , сам класс , как полагают, имеет неявный интерфейс, который мог бы иметь того же участника/типы как единственный интерфейс, но все еще означать что-то другое.
Это делает его более гибким, для того, когда существуют коллизии. В частности, посмотрите IEnumerator
и IEnumerator<T>
- они оба имеют Current
свойство, но различных типов. Вы имеете для использования явной интерфейсной реализации для реализации и (и универсальная форма, расширяет неуниверсальную форму).
Множественное наследование: Что, если Вы происходите из двух интерфейсов, определяющих тот же метод в различных целях?
interface IMoveable
{
public void Act();
}
interface IRollable
{
public void Act();
}
class Thing : IMoveable, IRollable
{
//TODO Roll/Move code here
void IRollable.Act()
{
Roll();
}
void IMoveable.Act()
{
Move();
}
}
Парни, спасибо за Ваши ответы.
оказывается, что "класс C# может наследоваться, один интерфейс и неявным и явным способом в то же время" является на самом деле иллюзией. На самом деле один класс может наследовать один интерфейс в течение одного времени.
В исходном вопросе, метод "DoSomething" кажется "неявно реализацией" интерфейс IFoo (метод на самом деле сгенерирован VS2008), но это на самом деле НЕТ. С явной реализацией интерфейса IFoo метод "DoSomething" поворачивается, чтобы быть просто нормальным методом, который не имеет никакого отношения к IFoo кроме с той же подписью.
я все еще полагаю, что это - хитрый дизайн C#, и это просто в использовании он по ошибке. Скажите, у меня есть некоторый код как это
Foo f = new Foo();
f.DoSomething();
Теперь, я хочу осуществить рефакторинг его к ниже кода. Это кажется отлично хорошо, но результат выполнения отличается.
Action<IFoo> func = foo => foo.DoSomething();
func(f);