Cum pot asigura că Linq către Sql nu suprascrie sau încalcă valorile implicite DB non-nullabile?

Am o DB SQL Server cu un tabel cu aceste câmpuri:

  1. Un bit cu valoarea implicită 1, NOT NULL .
  2. smalldatetime cu valoarea implicită gettime() NOT NULL int fără valoare implicită, IDENTITY , NOT NULL

Când generăm Linq la SQL pentru acest tabel, se întâmplă următoarele:

  1. Bitul nu este tratat special.
  2. smalldatetime nu este tratat special.
  3. int este marcat ca IsDbGenerated .

Acest lucru înseamnă că atunci când fac inserturi folosind Linq la SQL, se vor întâmpla următoarele:

  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?

Pentru a rezuma: Vreau câmpuri non-nullable cu valori implicite atribuite DB, dar nu le vreau IsDbGenerated dacă înseamnă că nu pot oferi valori pentru ele atunci când fac actualizări sau inserări folosind Linq la SQL. De asemenea, nu le vreau IsDbGenerated daca inseamna ca trebuie sa schimb mana codul generat de Linq catre SQL.

EDIT: Răspunsul pare a fi o limitare în Linq la SQL curent.

14
Duplicați: stackoverflow.com/q/1120858/11683 (nu votați să închideți, ambele sunt la fel de utile).
adăugat autor GSerg, sursa

4 răspunsuri

Schemele generate de linq-to-sql nu generează valoarea Constriganților impliciți.

Poate că în viitor, dar problema este constrângerile nu sunt întotdeauna simple valori, ele pot fi, de asemenea, funcții scalare ca GetDate() , astfel încât linq ar trebui cumva să știe cum să traducă aceste. Pe scurt, nici nu încerca. Este, de asemenea, un tip foarte specific de baze de date.

  • Puteți scrie un generator de cod pentru a crea clase parțiale ale entității, unde puteți extrage valoarea implicită prestabilită.
  • În mod alternativ, codul dvs. de nivel de afacere ar putea seta valorile implicite în constructori dintr-un fișier xml și tot ce trebuie să faceți este să păstrați fișierul xml actualizat.
  • În loc să faceți lucrul în constructori, puteți emula SQL și adăuga valori implicite prin inspectarea ChangeSet înainte de a trimite modificările la baza de date.

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

5
adăugat
"ar trebui cumva să știe cum să traducă acei" - de ce? S-ar putea să nu permită nimic să creeze/actualizeze și să le citească după aceea. Așa funcționează câmpurile IsDbGenerated, cu excepția stării lor de citire numai pe partea Linq.
adăugat autor bzlm, sursa
Sigur, ar putea permite, dar nu. IsDbGenerated este numai pentru coloanele cheie în acest moment. "Linq ar fi oarecum ..." este doar opinia mea de ce ar putea fi cazul.
adăugat autor Robert Paulson, sursa
pare că IsDbGenerated este acum disponibil și pentru coloanele non-cheie.
adăugat autor Make it useful Keep it simple, sursa

Am intrat în aceeași problemă, bzlm, și am ajuns la aceeași concluzie. Nu este pur și simplu o modalitate bună de a obține câmpuri non-nullable cu valori implicite atribuite DB care lucrează cu Linq To Sql.

Munca în jurul căreia am mers este de a adăuga o metodă SetDefaults() foarte asemănătoare cu aceea pe care Robert Paulson a legat-o cu CodeProject și apelați-o la constructorul implicit al clasei de bază a entității de masă. Ea funcționează bine pentru mine, pentru că 95% din timp, am setarea 0, șir gol, sau getdate ().

3
adăugat
Da la fel și aici. Mulțumiri!
adăugat autor bzlm, sursa

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.

Cel mai bun pariu este să le setați în constructorul obiectului sau în câmpurile private, dacă nu utilizați proprietăți automate.

2
adăugat
Este posibil, dar nu le poți schimba după fapt. Dacă doriți să le puteți schimba, atunci ar trebui să le creați în constructor.
adăugat autor David Basarab, sursa
Nu utilizați constructorul, există o metodă parțială specială numită OnCreate pentru aceasta. Vedeți această întrebare: stackoverflow.com/questions/82409/…
adăugat autor Sam, sursa
Se pare că vă spuneți că valorile implicite pentru câmpurile din valorile SQL Server NU sunt posibile pentru a fi combinate cu Linq To SQL. Este corect?
adăugat autor bzlm, sursa
Îmi pare rău, nu înțeleg. Ce este posibil? Și ce nu poate fi schimbat după ce fapt? Este posibil ca Linq Pentru SQL să efectueze o inserare și să aibă "valorile implicite" specificate în DB utilizat?
adăugat autor bzlm, sursa
De fapt, e OnCreated. Răspunsurile lui Longhorn213 sunt foarte confuze și mi-a redactat și întrebarea inițială pentru că nu are niciun motiv. Doar ignorați-l/ea.
adăugat autor bzlm, sursa

Puteți crea un alt fișier pentru datacontext (clasa parțială) și apoi utilizați metodele InsertYOURENTITY și UpdateYOURENTITY parțiale pentru a inspecta proprietățile și a atribui valorile corecte. Sunați ExecuteDynamicInsert sau ExecuteDynamicUpdate după codul dvs. și ați fost setat.

0
adăugat
De fapt, modul recomandat de a face acest lucru în BLL este de a implementa metoda parțială OnCreated() pentru entitate, nu metoda sugerată. Totuși, nu este relevant pentru întrebarea mea. Întrebarea mea este despre valorile implicite în SQL Server, nu în BLL.
adăugat autor bzlm, sursa