15 Stimmen

Linq To SQL ohne explizite Fremdschlüsselbeziehungen

Ich arbeite mit einigen Legacy-Tabellen, die Beziehungen haben, aber diese Beziehungen sind nicht explizit als Primär-/Fremdschlüssel festgelegt worden. Ich habe eine .dbml-Datei mit "Linq To Sql Classes" erstellt und die richtige Case.CaseID = CaseInfo.CaseID-Assoziation erstellt. Meine resultierende Klasse ist CasesDataContext.

Meine Tische (Einer zu vielen):

Case
------------------
CaseID (int not null)
MetaColumn1 (varchar)
MetaColumn2 (varchar)
MetaColumn3 (varchar)
...

CaseInfo
------------------
CaseInfoID (int)
CaseID (int nulls allowed)
CaseInfoMeta (varchar)
...

Ich bin neu bei LinqToSQL und habe Probleme mit

CasesDataContext db = new CasesDataContext();
var Cases = from c in db.Cases
            where c.CaseInfo.CaseInfoMeta == "some value"
            select c;

(Bearbeiten) Mein Problem ist, dass CaseInfo oder CaseInfos nicht als Mitglied von Cases verfügbar ist.

Ich habe von einem Kollegen gehört, dass ich ADO.Net Entity Data Model versuchen könnte, um meine Datenkontextklasse zu erstellen, aber ich habe das noch nicht ausprobiert und wollte sehen, ob ich meine Zeit verschwenden würde oder ob ich einen anderen Weg gehen sollte. Für Tipps, Links und Hilfe wäre ich sehr dankbar.

0 Stimmen

Haben Sie die DBML-Datei gespeichert? Ich glaube nicht, dass die CS-Dateien vor dem Speichern generiert werden. Das könnte der Grund dafür sein, dass CaseInfo nicht als Mitglied angezeigt wird.

0 Stimmen

@madcolor, ich habe in meiner Antwort eine Beispielkonfiguration gepostet, bitte sehen Sie sich diese an, da es sich wahrscheinlich um ein Problem mit der Beziehungskonfiguration handelt

26voto

eglasius Punkte 35447

Gehen Sie zurück zum Designer und überprüfen Sie, ob die Beziehung korrekt eingerichtet ist. Hier ist ein Beispiel aus der Praxis: BillStateMasters hat die Eigenschaft "CustomerMasters1" (Kunden für den Staat): alt text

Ps. die Namensgebung wird bereinigt ...

Aktualisierung 1: Sie müssen auch sicherstellen, dass beide Tabellen eine Primärdefinition haben. Wenn der Primärschlüssel nicht in der Datenbank definiert ist (oder aus irgendeinem Grund nicht definiert werden kann), müssen Sie ihn im Designer definieren. Öffnen Sie die Eigenschaften der Spalte, und legen Sie sie als Primärschlüssel fest. Abgesehen davon funktioniert die Entitätsverfolgung auch nicht, wenn Sie keinen Primärschlüssel für die Entität haben, was bei Löschungen bedeutet, dass die Entität nicht aktualisiert wird. Stellen Sie also sicher, dass Sie alle Entitäten überprüfen und dass sie alle einen Primärschlüssel haben (wie gesagt, wenn es nicht in der Datenbank sein kann, dann im Designer).

3 Stimmen

Freddy hat die Lösung.. Die einzige Einschränkung ist, dass Sie einen "Incorrect AutoSync specification for member error" erhalten, wenn Ihr Primärschlüssel auch ein Identitätsfeld ist. Möglicherweise müssen Sie Auto-Sync für diese Spalte im Designer abschalten.

1 Stimmen

Das Fehlen eines Primärschlüssels hat mich auf die Palme gebracht! Danke für die Hilfe

2 Stimmen

+1 für Primärschlüssel auch von mir. Ich habe fast eine Stunde lang mit dem Kopf gegen die Wand geschlagen. Danke!

5voto

Andrew Theken Punkte 3261
CasesDataContext db = new CasesDataContext();
var Cases = from c in db.Cases
            join ci in db.CaseInfo on
            ci.ID equals c.InfoID
            where ci.CaseInfoMeta == "some value"
            select new {CASE=c, INFO=ci};

meine "join" linq ist ein bisschen eingerostet, aber die oben sollte nahe an, was Sie suchen.

0voto

tvanfosson Punkte 506878

Ist die Zuordnung auf Eins zu Eins oder Eins zu Viele eingestellt? Wenn die Assoziation auf One to Many eingestellt ist, handelt es sich um ein EntitySet und nicht um eine EntityRef, und Sie müssen eine Where-Klausel für das abhängige Set verwenden, um den richtigen Wert zu erhalten. Ich vermute, dass Sie eine One-to-One-Beziehung wünschen, was nicht der Standard ist. Versuchen Sie, die Beziehung in One to One zu ändern und sehen Sie, ob Sie die Abfrage konstruieren können.

Anmerkung: Ich stelle nur Vermutungen an, weil Sie uns nicht gesagt haben, worin die "Probleme" eigentlich bestehen.

0voto

Randolpho Punkte 54011

Ihre Abfrage sieht korrekt aus und sollte eine Abfrageergebnismenge von Case-Objekten zurückgeben.

Wo liegt also das Problem?

(Bearbeiten) Mein Problem ist, dass CaseInfo nicht unter Cases verfügbar ist... d.h. c.CaseInfo existiert nicht dort, wo ich angenommen, es wäre, wenn es einen explizite Primär-/Fremdschlüssel Beziehungen gäbe.

Was meinen Sie mit "nicht verfügbar"? Wenn Sie die Assoziation im Designer erstellt haben, wie Sie sagen, dann sollte die Abfrage SQL generieren, das in etwa so aussieht

SELECT [columns] 
FROM Case INNER JOIN CaseInfo 
   ON Case.CaseID = CaseInfo.CaseID
WHERE CaseInfo.CaseInfoMeta = 'some value'

Haben Sie Ihre Linq-Abfrage debuggen, um die SQL generiert noch? Was gibt sie zurück?

0 Stimmen

Entschuldigung. Ich bin neu in Linq. CaseInfo wird nicht als ein Mitglied von Cases angezeigt.

0 Stimmen

Haben Sie die Assoziation im Designer erstellt? Gibt es eine CaseInfos-Eigenschaft?

0 Stimmen

Ich habe die Assoziation (übergeordnete Klasse = Fälle, untergeordnete Klasse = CaseInfo) für CaseID erstellt. Unter "Fälle" wird kein CaseInfo-Mitglied angezeigt.

0voto

Jeff Schumacher Punkte 3096

Es gibt ein paar Dinge, die Sie vielleicht ausprobieren sollten:

Überprüfen Sie die Eigenschaften der Vereinigung. Vergewissern Sie sich, dass die Eigenschaft Parent als Public erstellt wurde. Dies ist standardmäßig der Fall, aber vielleicht hat sich etwas geändert.

Da Sie nicht CaseInfo auf C erhalten, versuchen Sie es in die andere Richtung eingeben, um zu sehen, ob Sie ci.Case mit Intellisense erhalten.

Löschen Sie die Zuordnung und erstellen Sie sie neu.

Wenn die Kinder nicht erscheinen, läuft etwas ganz Grundlegendes schief. Es könnte am besten sein, die dbml zu löschen und das Ganze neu zu erstellen.

Wenn alles andere fehlschlägt, wechseln Sie zu NHibernate :)

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