• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

[C#] Datumsspanne überprüfen

Fluffy_Unicorn

Met-Brauer

Registriert
8 Aug. 2013
Beiträge
1.026
Ort
47.07°N / 7.85°O
Morgäääähhhhhnnnn liebe ngb-Gemeinde

Ich habe ein kleines Problem, oder vielleicht auch nur eine Denkblockade. In der Schulle müssen wir zur Zeit ein C#-Projekt mit EntityFramework und WPF umsetzen. Nun hänge ich bei einer bestimmten Stelle.

Im Projekt geht es um eine Objektvermietung. Wenn ich ein Objekt vermiete, muss ich natürlich überprüfen, ob die gewünschten Daten noch frei sind.

Beispiel:
Objekt ist vermietet vom 18.12.2013 - 21.12.2013
Gewünschte Mietspanne vom Benutzer: 22.12.2013 - 28.12.2013

Dies sollte natürlich keinen Fehler verursachen (21.12.2013 - 28.12.2013 sollte aber ein Fehler geben).

Mein Ansatz:

Wenn
gewünschtes Startdatum grösser als Ende der Vermietung
Oder
gewünschtes Enddatum kleiner als Anfang der Vermietung
= Erfolg

Dies klappt aber noch nicht ganz.
Mein Code (datePickerTo & DatePickerFrom sind dabei die Benutzereingaben):

[src=csharp]
IQueryable<vermietung> vermietungQuery = from vermietung
in vermietungContext.vermietung
where (vermietung.Startdatum > datePickerTo.SelectedDate
|| vermietung.Enddatum < datePickerFrom.SelectedDate)
&& vermietung.Objekt_id.Equals(object_id)
select vermietung;
[/src]

Wenn dann kein Datensatz gefunden wurde, kann die Vermietung vorgenommen werden.

Ich weiss nicht was falsch ist, wahrscheinlich stehe ich nur auf dem Schlauch irgendwie. Vielleicht ist auch mein gesamter Ansatz falsch.

Schonmal danke für eure Hilfe.
Gruss
 

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
Wenn
gewünschtes Startdatum grösser als Ende der Vermietung
Oder
gewünschtes Enddatum kleiner als Anfang der Vermietung
= Erfolg

Eigentlich hast du die Fälle:

-) Wenn keine bisherige Buchung erfolgt ist (leeres Result)
ODER
-) Wenn das Start Datum Größer als das vorherige End-Datum UND das End-Datum größer als das neue Start-Datum ist

==> Gültige Reservierung

Bei gewünschten Enddatum < Anfang der Vermietung würdest du zurück in die Zeit gehen und es wäre somit kein gültiges Datum.
 

Fluffy_Unicorn

Met-Brauer

Registriert
8 Aug. 2013
Beiträge
1.026
Ort
47.07°N / 7.85°O
  • Thread Starter Thread Starter
  • #3
Danke schonmal für die Antwort :)

Bei gewünschten Enddatum < Anfang der Vermietung würdest du zurück in die Zeit gehen und es wäre somit kein gültiges Datum.

Nein, denn eine Reservation kann auch im voraus getätigt werden. Wenn ich heute für Januar reserviere, muss ich trotzdem im Dezember noch reservieren können.
 

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
Ich sehe... eigentlich brauchst du ja 2 Datensätze. Folgendes Beispiel:

1.12 - 8.12
15.12 - 24.12
7.1. - 14.1

Das Datum welches du einspielen willst ist jetzt der 9.12 bis 14.12. Du überprüfst den ersten Datensatz, das neue Startdatum ist größer als das Enddatum, das passt soweit. Dann nimmst du dir den nächsten Datensatz her und überprüfst, ob das End-Datum kleiner als das Startdatum ist. Ist es kleiner hast du Erfolg, ist es größer oder gleich kannst du nicht reservieren. Sprich 9.12 - 14.12 würde funktionieren aber 9.12 bis 15.12 kannst du knicken.
 

Fluffy_Unicorn

Met-Brauer

Registriert
8 Aug. 2013
Beiträge
1.026
Ort
47.07°N / 7.85°O
  • Thread Starter Thread Starter
  • #5
Was meinst du mit 2 Datensätze?
Mit meiner SQL-Abfrage will ich ja diese Datensätze auslesen, die eine Kollision verursachen. Wenn es dann keine Kollision findet kann das Objekt vermietet werden.

9.12 bis 15.12 soll auch nicht gehen, da es ja ab dem 15.12 vermietet ist.

Bin wahrscheinlich grad etwas schwer von Begriff, entschuldigung dafür ;).
 

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
Ah, ich habe den Sinn deiner Abfrage falsch verstanden. Ich bin davon ausgegangen das du dir einfach 2 nahe gelegene Termine raussuchen willst und die dann manuell überprüfst und nicht über das Statement selbst abfragen möchtest. Ich muss das dann kurz durchdenken wie das am Besten funktioniert...

Boah das ist eine gewaltige Kopfnuss. Das Problem ist nämlich die Oder-Abfrage: Suchst du nur nach der Start-Zeit würdest du die Datensätze,die deine Bedingung (Startzeit > Endzeit) erfüllen, bekommen. Sprich im nachfolgenden Fall:

1.12 - 8.12
15.12 - 24.12
7.1. - 14.1

start > ende -> 1.12 - 8.12 würdest du als Datensatz bekommen


Da du jedoch eine Oder-Abfrage in deiner Abfrage drinnen hast kriegst du zusätzlich auch die Datensätze zurück wo das Ende < Starttermin ist - sprich bei 3 Einträgen kriegst du alle 3 wieder zurück, 1 von dem Start und 2 vom Ende.

Du brauchst also 2 Selects, einmal das du die Datensätze bekommst wo das Start-Datum größer als das End-Datum ist und dann eine wo das End-Datum kleiner als das Start-Datum ist. Sprich das wäre dann in Select 1 1.12 - 8.12 und in Select 2 15.12 - 24.12 sowie 7.1 bis 14.1. Jetzt müsstest du eigentlich von Statement 1 den letztmöglichen Eintrag nehmen (kann ja Zeiten davor auch existieren) und von Statement 2 den ersten Eintrag (ist der nächste Termin). Diese beiden müsstest du dann mit deinem neuen Datum vergleichen damit du siehst ob es da zu einem Problem wg. Terminüberschneidung kommt.

Meiner Meinung nach solltest du aber diese Überprüfung dann in deinem Code machen, sprich einfach die notwendigen Daten aus der DB ziehen und dann erst mit dem Datum abgleichen. Ist einfach "schöner" als da dir aus 2 Selects ein Ergebnis via Subselects zusammenzustoppeln und das dann zu verwursteln.
 
Zuletzt bearbeitet:

Exterminans

Neu angemeldet

Registriert
14 Juli 2013
Beiträge
147
Eigentlich trivial...

Es sind 3 Fälle möglich:
- Ein Startdatum liegt innerhalb des Zeitraums
- Ein Enddatum liegt innerhalb des Zeitraums
- Für einen einzelnen Eintrag liegt sowohl das Startdatum vor, als auch das Enddatum nach dem gewünschten Zeitraum

In allen 3 Fällen liegt eine Kollision vor, es gilt also:
[src=postgresql](reservierungen.startdatum BETWEEN date1 AND date2) OR (reservierungen.enddatum BETWEEN date1 AND date2) OR (reservierungen.startdatum <= date1 AND reservierungen.enddatum >= date2)[/src]
 

Kugelfisch

Nerd

Registriert
12 Juli 2013
Beiträge
2.342
Ort
Im Ozean
Mein Ansatz:
Wenn
gewünschtes Startdatum grösser als Ende der Vermietung [2]
Oder
gewünschtes Enddatum kleiner als Anfang der Vermietung [1]
= Erfolg
Grundsätzlich korrekt. Wenn du das jedoch so in LINQ-Notation überträgst
vermietung.Startdatum > datePickerTo.SelectedDate || vermietung.Enddatum < datePickerFrom.SelectedDate
selektierst du damit genau die Datensätze, welche unproblematisch sind. In deinem Beispiel würde die Abfrage bei einem Datenbestand von
1.12 - 8.12
15.12 - 24.12
7.1 - 14.1
und der Eingabe `9.12 - 15.12` die Resultate `1.12 - 8.12` (aufgrund von Bedingung 2) und `7.1 - 14.1` (aufgrund von Bedingung 1) liefern. Für `9.12 - 14.12` wäre das Ergebnis die komplette Liste, d.h. alle Einträge sind unproblematisch und die Buchung somit möglich.

Du möchtest aber wohl eher diejenigen Vermietungen selektieren, mit der Eingabe kollidieren. Dazu musst du die Bedingung negieren:
(vermietung.Startdatum <= datePickerTo.SelectedDate) && (vermietung.Enddatum >= datePickerFrom.SelectedDate)

Nachtrag:
Es sind 3 Fälle möglich:
- Ein Startdatum liegt innerhalb des Zeitraums
- Ein Enddatum liegt innerhalb des Zeitraums
- Für einen einzelnen Eintrag liegt sowohl das Startdatum vor, als auch das Enddatum nach dem gewünschten Zeitraum
Stimmt, allerdings müsste Fluffy_Unicorns Ansatz ebenfalls funktionieren, da in jedem dieser Fälle auch mindestens eine seine Bedingungen verletzt würde. Seine Bedingung [2] ist äquivalent zur Aussage `Der gewünschte Zeitraum A ist vollständig nach einem bestimmten Vermietungszeitraum B`, Bedingung [1] zur Aussage `Der gewünschte Zeitraum A ist komplett vor einem bestimmten Vermietungszeitraum B`. Wenn eine der beide Bedingungen erfüllt ist, sind A und B kollisionsfrei/disjunkt.
 
Zuletzt bearbeitet:

Fluffy_Unicorn

Met-Brauer

Registriert
8 Aug. 2013
Beiträge
1.026
Ort
47.07°N / 7.85°O
  • Thread Starter Thread Starter
  • #9
Sehr gut, werde die Lösungsansätze bei Gelegenheit mal testen.

An das Between habe ich gar nicht gedacht, geht sicher auch einfacher damit.

@Kugelfisch: Wieso hast du ein AND zwischen den zwei Bedingungen? Müsste das nicht ein OR sein?
 

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
Kugelfisch, wie intelligent ist LINQ? Weil das mit dem && habe ich auch überlegt, aber es sind ja eigentlich 2 Datensätze davon betroffen? Oder übersehe ich da das große Puzzlestück was mir gerade abgeht?
 

Kugelfisch

Nerd

Registriert
12 Juli 2013
Beiträge
2.342
Ort
Im Ozean
Wieso hast du ein AND zwischen den zwei Bedingungen? Müsste das nicht ein OR sein?
Nein, das ist eine Folge der Regeln von De Morgan, vgl. https://de.wikipedia.org/wiki/De_Morgansche_Gesetze - es gilt
NOT (A OR B) = (NOT A) AND (NOT B)

Kugelfisch, wie intelligent ist LINQ? Weil das mit dem && habe ich auch überlegt, aber es sind ja eigentlich 2 Datensätze davon betroffen?
Weshalb sollten zwei Datensätze betroffen sein? Die Bedingung muss sich ja gegen jeden einzelnen Datensatz (Bestehend zumindest aus aus Startdatum, Enddatum und Objekt-ID) unabhängig prüfen lassen, denn schliesslich ist die Frage, ob sich zwei Zeiträume überschneiden, unabhängig von beliebigen weiteren Zeiträumen. Die AND-verknüpften WHERE-Bedingungen müssen alle erfüllt sein, damit sich ein Treffer ergibt.
 

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
@Kugelfisch: *Bonk* Alles klar, ja, da hast du recht, ich hab mich zu sehr auf das "Zwischen zwei Daten" versteift.
 

Fluffy_Unicorn

Met-Brauer

Registriert
8 Aug. 2013
Beiträge
1.026
Ort
47.07°N / 7.85°O
  • Thread Starter Thread Starter
  • #14
So, habs getestet, und funktioniert einwandfrei.

Kugelfisch, du bist genial, danke vielmal ;).

Danke auch an alle anderen für die Hilfe.
 
Oben