2 Stimmen

Ändern des Datenkontexts eines LINQ-Objekts

Ich habe ein Objekt in SQL (A), das eine viele-zu-viele-Beziehung zu einem anderen Objekt (B) hat. Ich bin gerade dabei, eine API-Schicht-DLL zu erstellen, die es dem Benutzer ermöglicht, Objekte des Typs B dem Typ A zuzuordnen. Im Moment würde der Benutzer eine Liste von Einträgen des Typs A und eine Liste von Einträgen des Typs B mit verschiedenen LINQ-Datenkontexten abrufen. Das Problem ist, dass der mit A verbundene Datenkontext alle Objekte aus dem mit B verbundenen Datenkontext so behandelt, als ob sie neu wären, und versucht, sie einzufügen, wenn ich SubmitChanges() aufrufe. Gibt es eine Möglichkeit, dem Datenkontext A mitzuteilen, dass diese Objekte bereits existieren und nicht neu erstellt werden müssen? Der Code, den ich schreiben möchte, sieht in etwa so aus (ich rufe A Service und B Output auf):

List<Service> svcs = Service.GetServices();
List<Output> outs = Output.GetOutputs();

svcs[0].OutputCollection.Add(outs);
svcs[0].Save();

Jedes Service-Objekt in meinem Beispiel hat einen Verweis auf den Datenkontext, der es aus der Datenbank gezogen hat, und die Funktion Save ruft DataContext.SubmitChanges() auf; Der obige Code löst eine Ausnahme aus, weil er versucht, den bereits vorhandenen Output wieder zur Tabelle hinzuzufügen.

Ich weiß, das war lang und ich bin mir nicht sicher, ob ich mein Problem gut erklärt habe. Jede Einsicht oder jeder Vorschlag wäre hilfreich.

2voto

Mykroft Punkte 12677

Ich habe tatsächlich eine andere Art von Lösung gefunden und komme mir jetzt irgendwie dumm vor, weil ich die Frage überhaupt gestellt habe. Was ich in der Methode Service.Outputs.Add() gemacht habe, war wirklich das Problem:

public void Add(Output output)
{
    OutputCollectionItem oci = new OutputCollectionItem();
    oci.item = output;
    this.OutputCollection.Add(oci);
}

Was ich hätte tun sollen, ist:

public void Add(Output output)
{
    OutputCollectionItem oci = new OutputCollectionItem();
    oci.itemID = output.itemID;
    this.OutputCollection.Add(oci);
}

0voto

Chad Moran Punkte 12754

Ich hatte das gleiche Problem, aber ich konnte keine elegante Lösung finden. Aber die einzige Lösung, die ich fand, war entweder "Stitching" oder Reflexion zu verwenden.

Das Nähen sieht in etwa so aus.

Person existingPerson - DB.GetPerson(1);
existingPerson.BirthDate = newPerson.BirthDate;
existingPerson.JobTitle = newPerson.JobTitle;

Ich habe einmal etwas über die Verwendung eines Rückrufs gelesen, aber ich kann es beim besten Willen nicht mehr finden.

0voto

Davy Landman Punkte 14631

Ich denke, Sie müssen die Objekte von A und B trennen, sie dann verknüpfen und eine Anfügung in Ihrem Kontext durchführen, um sie wieder zu verbinden.

also:

// this remains
List<Service> svcs = Service.GetServices();
List<Output> outs = Output.GetOutputs();

svcs[0].OutputCollection.Add(outs);
svcs[0].Save();

// this changes
public class Service
{
    public static List<Service> GetServices()
    {
       var context = new Context();
       var result = context.ServiceSet.ToList();
       result.ForEach(e => context.Detach(e));
       return result;
    }
    public void Save()
    {
       var context = new Context();
       context.Attach(this); // will retach myself and all of my child entities.
       context.SaveChanges();
    }
}

public class Output
{
    public static List<Output> GetOutput()
    {
       var context = new Context();
       var result = context.OutputSet.ToList();
       result.ForEach(e => context.Detach(e));
       return result;
    }
}

0voto

Davy Landman Punkte 14631

Eine andere Lösung wäre, den Kontext zu teilen

Wenn Sie einen IoC-Container verwenden, können Sie die Lebensdauer Ihres Kontexts vom Container verwalten lassen. Bei einer Website ist es zum Beispiel eine gute Idee, die Lebensdauer Ihres Kontexts pro Anfrage zu koppeln.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X