2012-04-10 4 views
0

Beispielsituation (Ich habe dies direkter gefragt und keine Rückmeldung erhalten, also bitte entschuldigen Sie das abstrakte Beispiel, aber ich versuche nur, die Frage besser zu stellen):Wie kann ich feststellen, ob in einer EF-Entität eine abhängige Person fehlt?

Für die Kürze (tatsächliche Modelle sind Hunderte von Linien). Eine Datenbank wird modelliert, um Häuser darzustellen. Ein Haus kann Räume, Fenster und Höfe haben. Ein Raum kann Möbel oder Elektronik haben. Möbel können eine Couch, ein Tisch oder ein Stuhl sein. Eine Couch hat ein Muster, Material und Abmessungen.

Mr. F. Bars Haus ist ein Ausstellungsraum für die Crazy Couches von Bar. Jeden Monat zeigen die Zimmer von Mr. Bar Hunderte von Sofas. Mr. Bar mag es zu wissen, wann Leute seine Sofas mögen, und Feedback wird für jeden Raumaufbau aufbewahrt.

Mr. Ed, Mr. Bars Bruder, betreibt sein Datenbank-Management-System. Herr Ed beschließt, eine Couch zu entfernen, die eine Weile nicht benutzt wurde!

Angenommen, diese Löschung wird akzeptiert oder archiviert oder in einer Partition platziert oder als inaktiv markiert (d. H. Sie ist nicht blockiert, was hier eine Option ist).

Wie kann die Abwesenheit dieser abhängigen Couch in einem Haus bestimmt werden, das einen Raum hat, der die entfernte Couch von einer linq Abfrage mit Entity Framework 4.1 referenziert?

Die aufrufende Abfrage könnte so aussehen (aus Gründen der Kürze habe ich nur die aktuellen Teile verlassen), aber es hätte eine Ausnahme, die schwer zu erfassen ist.

public House getHouse(object id){ 
using(DbContext context = new FooBarContext()){ 
    DbSet<House> dbSet = context.Set<House>(); 
    IQueryable<House> query = dbSet; 
    query = query.Where(h => h.HouseKey == id); 
    query = query.Include(h => h.Room); 
    query = query.Include(h => h.Room.Couch); 
} 
return query.ToList(); 
} 

var house = getHouse(9).FirstOrDefault(); 

Das Haus wird mit dem richtigen Haus bevölkern. Es wird den richtigen Satz von Räumen enthalten. Ein Zimmer wird jedoch einen Verweis auf eine Couch haben, die kaputt ist. Jede try{}catch{} bis zu diesem Punkt wird dazu führen, dass keine Ausnahmen abgefangen werden. Dies ist nur für Haus mit Index Nummer 9. An diesem Punkt im Code könnte dies leicht eine Liste von vielen verschiedenen Hauskompositionen sein.

Wie kann ich sicherstellen, dass das Haus mit einem Raum, der eine entfernte Couch enthält, gefangen wird?

+0

Sie können nicht richtig? Diese Includes müssen manuell durchgeführt werden, um die Logik für das Screening einzubeziehen und können nicht über linq ausgeführt werden. –

+0

Kennen Sie die ID der fraglichen Couch? –

+0

@SteveMallory - Nicht vorher. –

Antwort

1

Wie Sie sich vorstellen können, wird dies nicht schön sein. Grundsätzlich müssen Sie eine linke Verbindung machen, dann greifen Sie auf alle Sofas von allen Häusern/Zimmern zurück. Wenn Sie versuchen, auf die schlechte Couch zugreifen, erhalten Sie eine SystemException:

A relationship multiplicity constraint violation occurred: 
    An EntityReference expected at least one related object, 
    but the query returned no related objects from the data store. 

try 
{ 
    var test = (from h in context.Set<House>() 
       join r in context.Set<Room>() 
        on h.Room.Id equals r.Id into houseRoom 
       from joinHouseRoom in houseRoom.DefaultIfEmpty() 
       join c in context.Set<Couch>() 
        on r.Couch.Id equals c.Id into houseRoomCouch 
       from joinHouseRoomCouch in houseRoomCouch.DefaultIfEmpty() 
       select h).ToList() 
         .Select(x => x.Room.Couch.Material) 
         .ToList(); 
} 
catch(SystemException se) 
{ 
    Console.WriteLine(se.Message); 
} 
+0

Beeindruckend :) Es sieht so aus, als ob ich eine Datenbanknormalisierung durchführen müsste, da ich lese, dass diese Art von Problem ein schlechtes Design anzeigt. –

+0

@TravisJ Ich würde definitiv empfehlen, Fremdschlüssel zwischen diesen Tabellen zu haben - lassen Sie den Datenbankserver tun, wozu er entwickelt wurde. Es würde verhindern, dass dieser Senario überhaupt eingreift. –

+0

Das wirkliche Problem hier ist Kaskadenlöschung und die Implikationen davon in der realen Welt. Obwohl eine Kaskadierung zur Aufrechterhaltung der Integrität erforderlich ist, kann dies zu Problemen bei der Entfernung wichtiger Daten führen.Die Vermeidung des Kaskaden (Hammer) -Ansatzes und das bloße Löschen eines einzelnen Datensatzes (Skalpell) ist der Ausgangspunkt für dieses Szenario. Ich schaute auf die Normalisierung, aber mein Schema ist 5NF und ich habe immer noch das Problem, wo die Entfernung eines abhängigen Datensatzes eine Inkonsistenz verursacht. Der Industriestandard dafür ist entweder "entferne die Aufzeichnung nicht" oder "entferne die Aufzeichnung und jeder, der jemals davon gehört hat" –

Verwandte Themen