Laden...

MSSQL "nur" bedingt mit EF4 auslesen

Erstellt von mik.keiser vor 13 Jahren Letzter Beitrag vor 13 Jahren 701 Views
M
mik.keiser Themenstarter:in
48 Beiträge seit 2007
vor 13 Jahren
MSSQL "nur" bedingt mit EF4 auslesen

verwendetes Datenbanksystem: MSSQL 2008 R2, Entity Framework 4, Silverlight, .NET 4.0, VS 2010

Guten Tag zusammen

Wie ihr in der Zeichnung am Anhang sehen könnt, habe ich eine Person mit 0...n Adressen.

Die Adressen werden historisiert, mit ValidFrom und ValidTo.

Nun möchte ich, mit LINQ eine Abfrage erstellen, die mir alle gewünschten Personen mit der aktuellen Adresse zurück gibt.

var vQuery = person FROM PersonSet WHERE person.Adresse.ValidTo >= DateTime.Now || person.Adresse.idAdresse == null SELECT person

Diese Abfrage gibt mir alle Personen zurück die eine gültige Adresse haben... Bei den Adressen werden nun aber alle geladen... Wie ihr in der Zeichnung sehen könnt möchte ich aber nur die aktuelle laden...

Beispiel: Wenn eine Person schon an 1'000'000 Adressen gewohnt hat bekomme ich 999'999 Datensätze die ich nicht brauche...

Gibt es da einen guten Ansatz?

Vielen Dank für Hilfe!

Grüsse MiK

W
955 Beiträge seit 2010
vor 13 Jahren

Hi,

Deine Anfrage sieht ungewöhnlich aus. Kompiliert das üebrhaupt oder hast Du es nur zur Verdeutlichung geschrieben?
Du kannst Dir im SQL Profiler mal anschauen welches SQL generiert wird und daraus versuchen Rückschlüsse zu ziehen.

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo,

wie witte bereits sagte kompiliert deine Anweisung nicht
From person in PersonSet[....]

Bei den Adressen werden nun aber alle geladen

Normalerweise nicht, denn deine LINQ-Query wird in SQL umgewandelt und somit führt die Query der Datenbankserver aus. Zurückgegeben und somit geladen werde nur jene Personen die auf die WHERE ansprechen.
Notfalls guck dir den generierten SQL-String an, damit du deine Zweifel beiseitelegen kannst.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

G
538 Beiträge seit 2008
vor 13 Jahren

Ich würde dann ja eher so etwas hier versuchen:

Adressen.Where(a => a.ValidFrom ≤ DateTime.Now && a.ValidTo ≥ DateTime.Now).Select(a => a.Personen)

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

M
mik.keiser Themenstarter:in
48 Beiträge seit 2007
vor 13 Jahren

Hallo zusammen

Das mit dem Query... hihi... war wohl etwas neben den Schuhen 😉

var vQuery = from person in oMichiTestDbEntities.PersonSet
                         join adress in oMichiTestDbEntities.AdresseSet on person.PersonID equals adress.adrPerson_FK
                         where adress.adrPostleitzahl == "9300"
                         select person;

Anstatt auf das ValidTo-Feld nehme ich jetzt eine Postleitzahl... das ist einfacher.

Gemäss meinem Profiler generiert das EF4 folgenden SQL:

SELECT [Extent1].[PersonID]      AS [PersonID],
       [Extent1].[perVorname]    AS [perVorname],
       [Extent1].[perNachname]   AS [perNachname],
       [Extent1].[perGeschlecht] AS [perGeschlecht],
       [Extent1].[perGebDatum]   AS [perGebDatum],
       [Extent1].[perAHVNummer]  AS [perAHVNummer]
FROM   [dbo].[Person] AS [Extent1]
       INNER JOIN [dbo].[Adresse] AS [Extent2]
         ON [Extent1].[PersonID] = [Extent2].[adrPerson_FK]
WHERE  N'9300' = [Extent2].[adrPostleitzahl]

Wie bekomme ich einen Left Join hin... So sollte der SQL aussehen...

SELECT [Extent1].[PersonID]      AS [PersonID],
       [Extent1].[perVorname]    AS [perVorname],
       [Extent1].[perNachname]   AS [perNachname],
       [Extent1].[perGeschlecht] AS [perGeschlecht],
       [Extent1].[perGebDatum]   AS [perGebDatum],
       [Extent1].[perAHVNummer]  AS [perAHVNummer]
FROM   [dbo].[Person] AS [Extent1]
       LEFT JOIN [dbo].[Adresse] AS [Extent2]
         ON [Extent1].[PersonID] = [Extent2].[adrPerson_FK]
WHERE  N'9300' = [Extent2].[adrPostleitzahl] OR [Extent2].[AdresseID] is null

Ich habe dieverse Anweisungen mit

.DefaultIfEmpty()

versucht...

Hat jemand eine Idee

W
955 Beiträge seit 2010
vor 13 Jahren

Eine Notlösung wäre mit UNION die Personen anzufügen welche noch keine Adresse besitzen.
Der Filter im Originalpost funktioniert vmtl nicht weil du in untergeordneten EntityCollectionen nicht filtern kannst. Also du kannst alle Personen mit ANY finden die schonmal in Berlin gewohnt haben oder wohnen du kannst aber nicht nach diesen Adressen filtern. (Also nur die Berliner Adressen in den Client laden in diesem Beispiel). Deshalb ist Grumbler85's Vorschlag interessant ich weiß aber nicht ob in seinem Beispiel das Relationship Span funktioniert also ob die Adresse dann noch dran ist. Außerdem fehlen die Personen welche keine Adressangaben besitzen, also das Union mal testen.