Da ich nicht in der Lage bin, einen Join zu erstellen, um erwartete Ergebnisse zu erzielen, habe ich angefangen zu denken, dass die ganze Architektur falsch ist.SQL SELECT JOIN und DB Architecture
Modelle (nur relevante Felder):
public class AspNetUsers // this is ASPNET default identity table modified
{
public string Id { get; set; }
public int GeoID { get; set; } // FK to GeoData PK
public string Email { get; set; }
public partial class Product
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int CategoryID { get; set; } // FK to Category PK
public string UserID { get; set; } // FK to AspNetUsers PK
public partial class Category
{
public int ID { get; set; }
public string Name { get; set; }
public class GeoData
{
public int ID { get; set; }
public DbGeography GeoLocation { get; set; }
public class WishList
{
public int ID { get; set; }
public string userEmail { get; set; } // FK to AspnetUsers 'Email'
public int frequency { get; set; }
public int category { get; set; } // FK to Category PK
public int range { get; set; }
public int geoid { get; set; } // FK to Geodata PK
Die Idee ist: Wir haben Produkte und Kategorien. Produkte sind benutzerbezogen. Die Benutzer-ID FK im Produktmodell berücksichtigt das, indem jedes Produkt mit seinem Besitzer in der AspNetUsers-Tabelle verknüpft wird, da jeder Benutzer sich registriert, sich über ASPnet-Identität anmeldet. Vor dem Einstellen ihrer Produkte müssen sich Benutzer selbst lokalisieren, damit ihre Produkte von anderen Benutzern bequem georeferenziert (gesucht) werden können. Die Geodaten-Tabelle berücksichtigt weltweite Koordinaten, Postleitzahlen, Ortsnamen usw. Nun zur WishList. Jeder Benutzer kann "n" Wunschlisten einrichten, die eine Kategorie festlegen, an der er interessiert ist, sowie einen Ort und einen Bereich von diesem Ort. Das Ergebnis der Whislist wird per SQL-Server per E-Mail an die Benutzer gesendet, die auf das Feld 'Häufigkeit' terminiert sind.
Ich bin mir nicht sicher, dass dies die bestmögliche db-Architektur ist. Manchmal beginnen Sie einfach mit einigen Bausteinen (AspNetUsers, Products, Categories) und fügen weitere Funktionen nach und nach hinzu. Wie dem auch sei .. Hier ist eine grundlegende SELECT, um die E-Mails zu erstellen, je nach Benutzer unterschiedlich Wunsch:
DECLARE C1 CURSOR READ_ONLY
FOR
SELECT [userEmail], [frequency], [category],[range], w.[geoid], [searchCity], u.UserName, g.[GeoLocation]
FROM WishLists as w
JOIN AspNetUsers as u ON w.userEmail = u.Email
JOIN GeoData_IT as g ON g.ID = w.geoid
OPEN C1;
FETCH NEXT FROM C1 INTO
@userEmail, @frequency, @category, @range, @geoid, @searchCity, @userName, @GeoLocation
WHILE @@FETCH_STATUS = 0
BEGIN
IF @geoid > 0
BEGIN
SELECT p.ID, c.Name, p.Name, g.PlaceName
FROM WishLists as w
RIGHT OUTER JOIN GeoData_IT AS g ON w.geoid = g.ID
JOIN AspNetUsers AS u ON g.ID = u.GeoID
JOIN Products as p on u.Id = p.UserID
JOIN Categories AS c ON p.CategoryID = c.ID
WHERE g.GeoLocation.STDistance(@GeoLocation) <= (@range*5000)
END
FETCH NEXT FROM C1 INTO
@userEmail, @frequency, @category, @range, @geoid, @searchCity, @userName, @GeoLocation
END
CLOSE C1;
DEALLOCATE C1;
GO
Ich bin nicht einmal die Einführung von ‚gesendet werden sollen Kategorie‘ Komplikation an dieser Stelle nur zu prüfen, ob der Wunschliste ein relevantes enthält Geoid (wenn Geoid> 0) versucht, für jede Wunschliste ein Produkt zu extrahieren, das zu Benutzern gehört, deren Geolokalisierung in dem gegebenen Bereich von dem gegebenen Geoid liegt. Aber ich bekomme ein doppeltes Ergebnis, zufällig nur auf einer bestimmten Wunschliste, und ich kann nicht herausfinden, warum.
Das sieht gut aus:
1 Nursery Loved Crib Bale Genoa
2 Baby products Crib Genoa
3 Baby products Cot Bed Genoa
4 Feeding Circus Crib Bale Genoa
Während diese Duplikate zeigt:
1555 Baby products this uaga product Recco
1555 Baby products this uaga product Recco
1556 Automotive uaga product Recco
1556 Automotive uaga product Recco
Ist die gesamte Architektur versagt oder nur die SELECT?
Es gibt mehrere Probleme mit Ihrem Datenmodell einschließlich, warum eine Wunschliste ein Geoid hat und warum hat sie die Useremail statt userId ? Außerdem sollten Produkte keine UserId haben. Die Wunschliste sollte die ProductId haben. Soweit die Auswahl und warum Du Duplikate hast? Es könnte sein, dass 2 Wunschlisten für zwei verschiedene Benutzer das gleiche Geoid haben und dann würden Sie zwei Zeilen wie Ihre Ergebnisse sehen. – Anand
1. Da userEmail in der AspNetUsers-Tabelle einzigartig ist, kann es als PK verwendet werden, wodurch die Einbindung von JOIN in vielen Fällen entfällt. 2. Es gibt eine Eins-zu-viele-Beziehung zwischen Benutzer-ID und Produkten. Sicher könnte ich die Architektur mit einer dritten Tabelle komplizieren: wäre das dringend ratsam? 3. Eine Wunschliste hat nichts mit einzelnen Produkten zu tun. Eine Wunschliste richtet sich auf einen Ort, einen Bereich von diesem Ort und schließlich auf eine Kategorie. Sicher, falls Benutzer nach zwei oder zwanzig identischen Wunschlisten fragen (nicht wirklich weise), werden sie nach identischen Ergebnissen, nach dem gleichen Ort, Entfernung und Kategorie fragen. – Luke
Ich erkannte nach meinem Kommentar, dass die Wunschliste standortbasiert war; Ich kann auch die userEmail in der Wunschliste ignorieren. Über (3) in Ihrem Kommentar ist das Problem nicht, wenn Benutzer identische Wunschlisten anfordern, das Problem ist, wenn zwei verschiedene Benutzer eine Wunschliste für das gleiche Geoid haben, erhalten beide Benutzer doppelte Zeilen durch Ihre SELECT-Anweisung '' 'FROM WishLists als w RECHTER ÄUSSERER JOIN GeoData_IT AS g ON w.geoid = g.ID VERBINDEN AspNetUsers AS u ON g.ID = u.GeoID''', weil Sie den Beitritt in der E-Mail verpassen. Abgesehen davon macht die Beziehung zwischen Benutzer und Produkt für mich keinen Sinn. – Anand