2010-06-07 2 views
2

나는 어떤 이유로이 사람에 방대한 두뇌 방구를 가지고 있습니다. 비즈니스를위한 "영업 시간"테이블이 있습니다. 표가 있습니다 - 일 (월요일 = 1, 일요일 = 7) 을 - 시간 시작 - 종료 시간SQL/C#의 영업 시간 #

내가 (SQL Linq에 사용) 깨끗한 코드를 작성하는 방법을 알아 내려고 노력하고있어이 그 것이다 새 시간 제출시 시간이 겹치지 않았는지 확인하고 그에 따라 모든 기록을 수정하십시오. 데이터베이스가 이미 이러한 기록이있는 경우 예를 들어, : - 시작 - = 오전 8시을 끝 = 정오 시작 = 오후 2, 끝 = 오후 5시

그리고 누군가가 추가 : - 시작 = 정오, 끝 = 오후 6시

나는 그 3 개의 레코드를 결합하여 하나의 레코드로 남겨 두는 방법을 코드가 알아 내길 원한다. 하지만 누군가가 이것을 삽입하는 경우 필요할 때만 결합 할 수 있어야합니다. - 시작 = 정오, 끝 = 오후 1시

그러면 두 개의 레코드가 수정됩니다. 첫 번째는 수정됩니다.

내가 말했듯이 ... 나는 이것만으로 내 머리를 감싸고있는 것처럼 보일 수 없다. 도움 말 하시겠습니까?

+0

http://stackoverflow.com/questions/1233292/whats-a-good-generic-algorithm-for-collapsing-a-를 삽입 잠재적으로 중복되는 세트 – jball

답변

2

시간 간격 표현을 약간 변경하고 EndTime 대신 Length 속성을 사용하는 것이 좋습니다.

class TimeInterval 
{ 
    public int Day { set; get; } 
    public DateTime StartTime { set; get; } 
    public int Length { set; get; } 
} 

겹치는 간격을 찾는 데 관심이 있으니 다음 방법을 사용하면 편리합니다. 나는 이것을 TimeInterval 클래스 안에 넣을 것입니다.

public int StartMinuteInWeek() 
{ 
    return Day * 24 * 60 + StartTime.Hour * 60 + StartTime.Minute; 
} 

public int EndMinuteInWeek() 
{ 
    return StartMinuteInWeek() + Length; 
} 

그러면 새로운 시간 간격과 겹치는 모든 TimeInterval을 찾아야합니다. 새로운 간격은 기존의 간격을 확장하거나 두 개의 개별 간격을 결합하거나 이미 정의 된 간격에 포함될 수 있음을 알아야합니다.

은 간격의 시작에 중복 레코드를 얻을 다음 쿼리를 사용하려면

var startOverlap = (from rec in intervals 
    where rec.StartMinuteInWeek() <= timeInterval.StartMinuteInWeek() && rec.EndMinuteInWeek() >= timeInterval.StartMinuteInWeek() 
    select rec).FirstOrDefault(); 

timeInterval가 추가하려는 새로운 간격입니다. startOverlap가 널이면

var endOverlap = (from rec in intervals 
    where rec.StartMinuteInWeek() <= timeInterval.EndMinuteInWeek() && rec.EndMinuteInWeek() >= timeInterval.EndMinuteInWeek() 
    select rec).FirstOrDefault(); 

이 다음 구간의 시작에서 중첩이 없다 : 단부 대

는 한 다음 사용 중첩된다. endOverlap에서도 마찬가지입니다. startOverlap == endOverlap 인 경우, 새 간격은 이미 존재하는 간격 안에 완전히 포함됩니다.

StartTime을 DateTime 유형으로 정의했는데 시간 부분에만 관심이 있지만 Hour 및 Minute라는 두 개의 필드 또는 시작 분을 나타내는 유일한 필드가 필요한 경우이 값을 변경할 수 있습니다 그 간격의 주에

나는 내 댓글에서 언급 한 바와 같이 편집

, 나는 새로운 시간 간격이 몇 이미 정의 된 간격을 겹칠 수 있음을 깨달았다.예를 들어 정상적으로 작업이 8:00에서 20:00에 진행되고 점심 시간에 중지하고 24x7 주 내내 통과하는 새 시간 간격이 정의되면 새 시간 간격에 14 개의 간격이 포함됩니다.

이것을 통과하는 안전한 방법은 먼저 모든 겹쳐진 간격을 감지 한 다음 새 간격을 조정하여 겹쳐진 간격을 완전히 포함하고 마지막으로 모든 겹침을 삭제하는 것입니다.

새 간격이 이전 간격과 겹치는 지 알아 보려면 TimeInterval 클래스에서이 편리한 방법을 정의하겠습니다.

public bool IsInsideInterval(int minuteInWeek) 
{ 
    return minuteInWeek >= StartMinuteInWeek() && 
     minuteInWeek <= EndMinuteInWeek(); 
} 

이제 시작 간격 또는 종료 분이 새 간격 안에 있음을 알 수 있습니다.

var overlaps = (from rec in intervals where 
    newInterval.IsInsideInterval(rec.StartMinuteInWeek()) || 
    newInterval.IsInsideInterval(rec.EndMinuteInWeek()) 
    select rec).ToList(); 

이제 새 간격 제한이 올바른지 확인해야합니다.

foreach (TimeInterval rec in overlaps) 
{ 
    if (rec.StartMinuteInWeek() < newInterval.StartMinuteInWeek()) 
    { 
     newInterval.Day = rec.Day; 
     newInterval.StartTime = rec.StartTime; 
    } 
    if (rec.EndMinuteInWeek() > newInterval.EndMinuteInWeek()) 
    { 
     // You have to calc the Length being careful to not count twice the minutes that overlaps. 
     newInterval.Length = newInterval.Length + rec.Length - (newInterval.EndMinuteInWeek() - rec.StartMinuteInWeek()); 
    } 
} 

마지막으로 당신은 overlaps의 모든 간격을 삭제하고 newInterval

+0

나는 처음에 생각한 것보다 조금 더 까다로운 문제라는 것을 깨닫게되었습니다. 새로운 시간 간격은 이미 정의 된 여러 간격과 겹칠 수 있습니다. 나는 지금 갱신 중이다! – Fede

관련 문제