Wie kann ich sicherstellen, dass Linq to Sql die Standardwerte für nicht nullbare DBs nicht überschreibt oder verletzt?

Ich habe eine SQL Server DB mit einer Tabelle mit diesen Feldern:

  1. Ein -Bit mit dem Standardwert 1, NOT NULL .
  2. Ein smalldatetime mit dem Standardwert gettime() , NOT NULL .
  3. Ein int ohne Standardwert, IDENTITY , NOT NULL .

Wenn ich Linq to SQL für diese Tabelle erzeuge, passiert Folgendes:

  1. Das -Bit wird nicht speziell behandelt.
  2. Der smalldatetime wird nicht speziell behandelt.
  3. Der int ist als IsDbGenerated .
  4. gekennzeichnet

Das bedeutet, dass wenn ich Einfügungen unter Verwendung von Linq zu SQL mache, geschieht Folgendes:

  1. The bit will be sent as 0, overriding the default value. Right?
  2. The smalldatetime will be sent as an uninitialized System.DateTime, producing an error in SQL server since it doesn't fall with the SQL Server smalldatetime range. Right?
  3. The IsDbGenerated int will not be sent; the DB will generate a value which Linq to SQL will then read back.

What changes do I have to make to make this scenario work?

Zusammenfassend: Ich möchte nicht-NULL-fähige Felder mit DB-zugewiesenen Standardwerten, aber ich möchte sie nicht IsDbGenerated wenn es bedeutet, dass ich keine Werte für sie angeben kann, wenn ich Aktualisierungen oder Einfügungen mit Linq to SQL vorstelle. Ich will sie auch nicht IsDbGenerated , wenn das bedeutet, dass ich den von Linq generierten Code manuell an SQL anpassen muss.

EDIT: Die Antwort scheint zu sein, dass dies eine Einschränkung im aktuellen Linq zu SQL ist.

14
Duplizieren: stackoverflow.com/q/1120858/11683 (nicht stimmen, um zu schließen, sind beide gleichermaßen nützlich).
hinzugefügt der Autor GSerg, Quelle

4 Antworten

Von Linq-To-Sql generierte Klassen übernehmen nicht die Standardwert-Constrients.

Vielleicht in der Zukunft, aber das Problem ist, dass Einschränkungen nicht immer einfache Werte sind, sie können auch skalare Funktionen wie GetDate() sein, also müsste linq irgendwie wissen, wie man diese übersetzt. Kurz gesagt, es versucht es nicht einmal. Es ist auch eine sehr datenbankspezifische Art von Sache.

  • Sie könnten einen Code-Generator schreiben, um Entity-Teilklassen zu erstellen, in denen Sie den Standardwert constriant extrahieren können.
  • Alternativ dazu kann der Business-Layer-Code die Standardwerte in Konstruktoren aus einer XML-Datei festlegen, und Sie müssen lediglich die XML-Datei auf dem neuesten Stand halten.
  • Anstatt die Arbeit in Konstruktoren auszuführen, könnten Sie sql emulieren und Standardwerte hinzufügen, indem Sie das ChangeSet vor dem Übermitteln von Änderungen an die Datenbank überprüfen.

The issue you are having is described at length in CodeProject - Setting Default Values for LINQ Bound Data

5
hinzugefügt
"linq müsste irgendwie wissen, wie man diese übersetzt" - warum? Es könnte einfach erlauben, nichts auf create/update zu übergeben und sie danach wieder zu lesen. So funktionieren IsDbGenerated-Felder mit Ausnahme ihres schreibgeschützten Status auf der Linq-Seite.
hinzugefügt der Autor bzlm, Quelle
Sicher, es könnte es erlauben, aber es tut es nicht. IsDbGenerated gilt nur für Schlüsselspalten zu diesem Zeitpunkt. Die "linq wäre irgendwie ..." ist nur meine Meinung, warum dies der Fall sein könnte.
hinzugefügt der Autor Robert Paulson, Quelle
scheint, dass IsDbGenerated nun auch für Nicht-Schlüsselspalten verfügbar ist.
hinzugefügt der Autor Make it useful Keep it simple, Quelle

Ich bin auf das gleiche Problem gestoßen, bzlm, und komme zu demselben Schluss. Es gibt einfach keinen guten Weg, nicht-nullbare Felder mit DB-zugewiesenen Standardwerten zu erhalten, die mit Linq To Sql arbeiten.

Die Arbeit, um die ich gegangen bin, besteht darin, eine SetDefaults() -Methode hinzuzufügen, die der von Robert Paulson, die mit CodeProject verknüpft ist, sehr ähnlich ist und sie im Standardkonstruktor meiner Tabellenentitäts-Basisklasse aufruft. Es funktioniert gut für mich, weil 95% der Zeit, ich eine 0, leere Zeichenfolge oder getdate() festlegen.

3
hinzugefügt
Ja, es geht mir genauso. Vielen Dank!
hinzugefügt der Autor bzlm, Quelle

This means that when I make inserts using Linq to SQL, the following will happen:

  1. The bit will be sent as 0, overriding the default value. Right? - Correct
  2. The smalldatetime will be sent as an uninitialized System.DateTime, producing an error in SQL server since it doesn't fall with the SQL Server smalldatetime range. Right? - What is sent is DateTime.MinValue
  3. The IsDbGenerated int will not be sent; the DB will generate a value which Linq to SQL will then read back. - If DB generated is set then the value is created by the database, if not then Linq expects the user to set the value.

Am besten setzen Sie sie im Konstruktor des Objekts oder in den privaten Feldern, wenn Sie keine automatischen Eigenschaften verwenden.

2
hinzugefügt
Es ist möglich, aber Sie können sie nach der Tat nicht ändern. Wenn Sie sie ändern können, sollten Sie sie im Konstruktor erstellen.
hinzugefügt der Autor David Basarab, Quelle
Verwenden Sie den Konstruktor nicht, dafür gibt es eine spezielle partielle Methode namens OnCreate. Siehe diese Frage: stackoverflow.com/questions/82409/…
hinzugefügt der Autor Sam, Quelle
Es klingt wie Sie sagen, dass Standardwerte für Felder in SQL Server-Werten nicht möglich sind, mit Linq To SQL zu kombinieren. Ist das richtig?
hinzugefügt der Autor bzlm, Quelle
Entschuldigung, ich verstehe es nicht. Was ist möglich? Und was kann nach welcher Tatsache nicht geändert werden? Ist es möglich, dass Linq To SQL eine Einfügung durchführt und die in der DB angegebenen "Standardwerte" haben?
hinzugefügt der Autor bzlm, Quelle
Eigentlich ist es OnCreated. Longhorn213's Antworten sind sehr verwirrend, und er/sie hat meine ursprüngliche Frage auch scheinbar ohne Grund bearbeitet. Ignoriere ihn einfach.
hinzugefügt der Autor bzlm, Quelle

Sie können eine weitere Datei für Ihren Datenkontext (Teilklasse) erstellen und anschließend die Teilmethoden InsertYOURENTITY und UpdateYOURENTITY verwenden, um Ihre Eigenschaften zu überprüfen und die richtigen Werte zuzuweisen. Rufen Sie ExecuteDynamicInsert oder ExecuteDynamicUpdate nach Ihrem Code auf und Sie sind fertig.

0
hinzugefügt
Die empfohlene Vorgehensweise in der BLL ist die Implementierung der partiellen Methode OnCreated() für die Entität, nicht die von Ihnen vorgeschlagene Methode. Trotzdem ist es für meine Frage nicht relevant. Meine Frage bezieht sich auf Standardwerte in SQL Server, nicht in der BLL.
hinzugefügt der Autor bzlm, Quelle