2009-05-11 9 views
0

Wie soll ich mit einer benutzerdefinierten Eigenschaft in einer Situation umgehen, in der ich Teilklassen mit den EF-generierten Klassen verwende?Verwenden von Teilklassen in Entity Framework mit benutzerdefinierten Eigenschaften

Hier ist das Setup:

Timesheet Tabelle - diese speichert eine Stunde des Mitarbeiters
- TimeSheetID (auto, int, PK)
- Entrydate (Datetime)
- Hours (int)
- EmployeeID (int)

EmployeeHourlyRate-Tabelle - speichert den aktuellen Stundensatz eines Mitarbeiters. Historische Preise werden auch hier gespeichert.
- RateID (int, PK)
- EffectiveDate (int, PK)
- Rate (double)

Dies ist eine Eins-zu-Beziehung von Timesheet zu EmployeeHourlyRate. Um die Rate eines Mitarbeiters zu finden, würde ich das maximale effektive Datum weniger als das EntryDate des timeSheets auswählen.

Um Dinge zu erleichtern, habe ich eine Teilklasse namens TimeSheet gemacht und eine neue Eigenschaft namens "Rate" zu dieser Klasse hinzugefügt. Was ich tun möchte, beziehe ich selbst aus derselben Abfrage, die meine Sammlung von TimeSheets füllt. Ich kenne einfach keinen einfachen und sauberen Weg, damit umzugehen.

Zum Beispiel könnte ich es auf diese Weise tun:

var list = from ts in Context.TimeSheets 
      .... 
      select new TimeSheet() { 
       TimeSheetID = ts.TimeSheetID, 
       EntryDate = ts.EntryDate, 
       Hours = ts.Hours, 
       EmployeeID = ts.EmployeeID, 
       Rate = SomeRate //real code has been omitted 
      }; 

Diese in der Theorie funktionieren sollte, aber aus irgendeinem Grund die EF beschwert sich während der Laufzeit, dass ich eine Einheit generierte Klasse wiederverwenden (keine Ahnung, warum - es funktioniert gut, wenn ich meine eigene benutzerdefinierte Klasse erstellen). Aber selbst wenn es funktioniert, muss ich immer noch eine Liste von Feldern verwalten und von meinem EF zu einer einzigen Klasse mappen - d. H. Wartung wird zu einem Problem, wenn/wenn ich der TimeSheet-Tabelle neue Felder hinzufüge. Es ist auch dumm, all diese Informationen neu eingeben zu müssen.

Meine Frage ist also, wie gehen die Leute im Allgemeinen mit diesem Szenario um? Gibt es eine Möglichkeit, etwas im Datamodel zu tun, das meine Join-Regel (über die Auswahl des richtigen effektiven Datums basierend auf meinem EntryDate) effektiv kennen und damit umgehen könnte?

+0

Es ist ein wenig schwierig zu sagen mit dem kleinen Code-Schnipsel, den Sie bereitgestellt haben. Vielleicht der Rest deiner partiellen Klasse ... –

Antwort

2

Ich mag würde Ihre vollständige LINQ-Abfrage (einschließlich der ‚SomeRate‘ Code), um zu sehen, genau zu sehen, was Sie erreichen wollen, aber vielleicht so etwas funktionieren könnte:

ACHTUNG: Air-Code.

public partial class TimeSheet 
{ 
    public double Rate 
    { 
     get //Calculate your rate here... e.g. 
     { 
      if ((this.Employee == null) || (this.Employee.EmployeeHourlyRates.Count == 0)) 
       //throw an exception 

      EmployeeHourlyRate maxRate; 
      foreach (EmployeeHourlyRate rate in this.Employee.EmployeeHourlyRates) 
      { 
       if ((rate.EffectiveDate <= this.EntryDate) 
        && ((maxRate == null) || (maxRate.EffectiveDate < rate.EffectiveDate))) 
       { 
        maxRate = rate; 
       } 
      } 

      if (maxRate == null) 
       //throw exception 
      else 
       return maxRate.Rate; 
     } 
    } 
} 

BEARBEITEN: Hinzufügen eines Beispiels für eifriges Laden, um Datenbankumläufe zu vermeiden.

var list = from ts in Context.TimeSheets.Include("Employee.EmployeeHourlyRate") 
      where blah blah 
      select ts; 
+0

Das könnte funktionieren, und zwar sehr schön, wenn es nicht einen zusätzlichen Datenbanktreffer verursachen würde. Das Objekt wird in einem Gridview-Szenario verwendet ... Wenn das Grid 50 Datensätze enthält, fragt jeder dieser Datensätze die Datenbank ab und verursacht einige große Verzögerungen. – bugfixr

+0

Je nachdem, wie die Datenbank ausgeführt werden soll, können Sie die zugehörigen Entitäten entweder "eifrig laden" (siehe beispielsweise meine bearbeitete Antwort) oder die Entitäten mithilfe einer Kombination aus .Load() & .IsLoaded() "verzögern". ... nur du weißt, was der beste Weg wäre. – Charlino

Verwandte Themen