2009-05-22 2 views
0

Gestern fragte ich this question in Bezug auf Best Practices für ein einfaches Information Retrieval-System Ich fange an zu arbeiten.Wie behandelt man die programmatische Addition von Feldern?

Heute hat mein Kunde mich gefragt, ob es möglich ist, dass sie Felder zu der primären Entität zu einem späteren Zeitpunkt über die Verwaltungsschnittstelle hinzufügen können. Das heißt, die Anwendung erlaubt Ihnen, über eine Datenbanktabelle zu suchen (nennen wir sie Entitäten), die verschiedene Assoziationen zu anderen Objekten haben kann, aber der Fokus liegt auf den Entitäten.

Nun, natürlich ist der Himmel die Grenze, und das ist möglich.

Mein erster Gedanke, mit diesem Problem zwei neue Tabellen zu erstellen ist:

AdditionalFields (FieldID PK, Feldname, IsShownInSearchResults und andere Metadaten) Dies ist die Tabelle, die seine Reihen geführt hätte durch die Admin-Oberfläche. Zum Beispiel, wenn der Kunde später entscheidet, dass sie die Fähigkeit hinzufügen möchten, sagen wir, die Augenfarbe einer Entität, würden sie ein AdditionalField mit einem FieldName von "Augenfarbe" erstellen.

AdditionalFieldData (FieldDataID PK, EntityID FK, FK FieldID , Fieldvalue) Dies ist die Tabelle durch den Kunden die Entitäten auf die jeweiligen Werte für zusätzliche Felder hinzugefügt beziehen. Wenn wir zum Beispiel bei unserem Augenfarbenbeispiel zwei Entitäten (EntityID 3 und 4) zum Zeitpunkt der Hinzufügung des Feldes und das neue AdditionalField eine FieldID von 1 haben, ist es zulässig, dass keine Augenfarbendaten mit den Entitäten verknüpft sind . Der Kunde könnte dann wählen, die Augenfarbe "Blau" zu Entität 3 hinzuzufügen, und wir würden eine Zeile in AdditionalFieldData wie folgt einfügen: (autogenerated PK, 3, 1, "Blau").

Da ich leicht über diese suchen möchte, werde ich einfach verlangen, dass alle zusätzlichen Felder Zeichenfolgenwerte haben.

Nach dem Ansatz, den ich in der vorherigen Frage geschrieben habe, würde ich Linq-To-SQL mit einer Abfrage ähnlich der folgenden für Informationsabruf verwenden, wenn ein Benutzer eine Suche durchführt (natürlich wird die Logik für die Filterung sein komplexer in der Praxis):

var results = from s in db.Stuff 
      where (s.Name.Contains(textFilter) || 
       s.Title.Contains(textFilter)) 
      select s; 

ich die Abfrage ändern würde wie folgt aussehen:

var results = from s in db.Stuff 
       where (...existing filter logic...) || 
        s.AdditionalFieldData.Any(afd => afd.FieldName.Contains(textFilter)) 
       select s; 

Also meine Frage ist: ist das sinnvoll? Gibt es eine bessere Lösung, die ich verpasst habe? Gibt es irgendwelche Auswirkungen dieses Ansatzes, die mir bewusst sein sollten?

(Bitte verzeihen Sie meine dummen Identifikatoren, seine früh für mich :)

Antwort

1

Ich bin kein LINQ-Experte, aber aus einer Datenbank-Design Sicht, was schlagen Sie scheint mir einfach gut.

Eine Alternative, die ich ein paar Mal verwendet habe, ist, eine ganze Reihe von "Ersatz" -Feldern in der Entities-Tabelle zu definieren, die die Benutzer über die Admin-Schnittstelle aktivieren/deaktivieren können. Sie erhalten auf diese Weise eine gewisse Datenbankleistung (aufgrund der geringeren Anzahl von Joins), aber Sie müssen im Voraus auswählen, wie viele dieser Ersatzfelder Sie haben möchten, und Sie haben die meiste Zeit große, meist leere Tabellen.

Oh, und Sie können sicher davon ausgehen, dass, wenn Sie wählen N Ersatz Felder hinzuzufügen, wird Ihre Benutzer wollen N + 1 ;-)

Verwandte Themen