| 

.NET C# Java Javascript Exception

1
Hallo,

ich bekomme folgende Fehlermeldung, die ich nicht auflösen kann.
"Die Beziehung zwischen den beiden Objekten kann nicht definiert werden, da sie an verschiedene ObjectContext-Objekte angefügt wurden."

Ich habe einen UnitTest, indem ich ein Objekt (Material) erzeuge. Dieses Objekt ist ein Objekt aus dem Proxy von EF. Dieses wird an eine Methode übergeben, welche in Abhängigkeit von einem String-Inhalt ein Property (Collection von Element -> ebenfalls EF mit einem Property welches eine Referenz auf ein StandardElement enthält) ergänzen soll

Der Code sieht wie folgt aus
private void ParseElementTag (string line, Material material)
{
const string ERR_MSG = "A material element definition [{0}] was invalid. It should have had 4 Segments and had {1}.";
StandardElement stdElement;

string[] parts = line.Replace (" ", String.Empty).Split (':');

if (parts.Length != 4)
throw new MaterialInvalidArgumentException (String.Format (ERR_MSG, line, parts.Length));

string sym = (parts[3] == QuestionMark || String.IsNullOrEmpty (parts[3])) ? String.Empty : parts[3];

using (XPRDrptEntities db = new XPRDrptEntities ())
{
int id;

if ((id = ConversionUtility.ToInteger (parts[0], "INT32")) == 0)
{
if (sym == String.Empty || !StdElement.ExistsElement (db, sym))
throw new MaterialInvalidArgumentException (String.Format ("Invalid material element definition [{0}]", line));
}
else if (!StdElement.ExistsElement (db, id))
throw new MaterialInvalidArgumentException (String.Format ("Invalid material element definition [{0}]", line));

stdElement = id == 0 ? StdElement.GetStandardElement (db, sym) : StdElement.GetStandardElement (db, id);
}

Element element = new Element
{
minPPM = ConversionUtility.ToReal (parts[1], 0, Double.MaxValue, 0),
maxPPM = ConversionUtility.ToReal (parts[2], 0, Double.MaxValue, Double.MaxValue),
StandardElement = stdElement
};
// !!!!! hier kommt es zu der Fehlermeldung !!!!
material.Elements.Add (element);
}


An der Fehlerstelle hat die Zuweisung des stdElements, also der Referenz, stattgefunden. Erst bei dem Versuch das Element der EntityCollection<Element> hinzuzufügen kracht es.

Der UnitTest sieht im Prinzip wie folgt aus:

...

Material _material = new Material ();
foreach (string line in lines)
try
{
Isolate.Invoke.Method (txt, "ParseElementTag", line, _material);
Console.WriteLine (String.Format ("logic passed with: {0}", line));
}
catch (MaterialInvalidArgumentException ex)
{
// Info: Should be intercepting a call to the logger!
Console.WriteLine ("Test failed. Should not have thrown an exception! ERROR: {0}", ex.Message);
}
...


Für jeglichen Hinweis/Hilfe wäre ich echt dankbar, da ich total auf dem Schlauch stehe.

Peter
27.05.2011
mph 227 1 6
1 Antwort
1
Mit XPRDrptEntities db = new XPRDrptEntities () erzeugst du meiner Meinung nach einen neuen ObjectContext. Dieser ist dann grundsätzlich anders, als der aus dem du deine Materialien gezogen hast.

Du musst dir ObjectContext wie eine separaten Abhängigkeitsbaum vorstellen. Daten die in einem Context vorhanden sind, müssen nicht zwangsläufig in einem anderen sein. Wenn du dir nun einen Kontext hälst um dein Element aus der Datenbank zu lesen, kannst du dieses Element nicht in den Materialbaum einhängen, da es dort nicht existiert.

Wenn du also die Elemente eines Materials beeinflussen willst musst du diese auch beim gleichen Context wie das entsprechende Material anfordern.
27.05.2011
Hendrik Lösch 1,5k 1 9
Danke für den Hinweis.
Material ist ein Objekt, welches von XPRDrptEntities (ein Objekt welches mir den Zugang zur Datenbank erlaubt) verarbeitet wird. Also aus der DB und in die DB geschrieben werden kann.

Das neue Material ist ohne Kontext erzeugt worden und StdElement wird aus der DB mit einem Datensatz gefüllt. Ich habe mir nun vorgestellt, dass ich diesen einem Element (wiederum ohne Kontext) als Property zuweisen kann.

Liege ich falsch?
mph 27.05.2011
Ich kenne von EF leider fast nur die Theorie und habe es nocht nicht wirklich eingesetzt. Aus diesem Grund kann ich keine verlässliche Antwort auf die Frage geben.

Trotzdem fällt mir auf, dass dein Element sehr wohl Bezug auf die DB nimmt denn du machst ja im Objectinitializer: StandardElement = stdElement
stdElement hast du dir aber von deiner Datenbank geben lassen.

Warum solltest du sonst bei folgendem Code die db-Variable mit übergeben: StdElement.GetStandardElement (db, sym)
Hendrik Lösch 27.05.2011
Hmm, okay ich versuche es mal so.
Vielen Dank für Deine Zeit und Hilfe!
mph 06.06.2011
Sollte es klappen, kannst du die Antwort ja als Lösung markieren :)
Hendrik Lösch 09.06.2011

Stelle deine Framework-Frage jetzt!