Kako postaviti pametne telefone i računala. Informativni portal
  • Dom
  • Željezo
  • Eksplicitna naznaka vrste stupca. Promjena kodiranja niza iz Unicodea u ASCII

Eksplicitna naznaka vrste stupca. Promjena kodiranja niza iz Unicodea u ASCII

Označava da je novi stupac stupac identiteta. Kada se doda u tablicu nova linija mehanizam baze podataka generira jedinstvenu sekvencijalnu vrijednost za ovaj stupac. Stupci identiteta obično se koriste s ograničenjem PRIMARY KEY za održavanje jedinstvenih identifikatora redaka u tablici. Svojstvo IDENTITY može se dodijeliti tinyint, smallint, int, bigint, decimalni (p, 0) ili numerički (p, 0) stupac. Za svaku tablicu može se kreirati samo jedan stupac identiteta. Zadane vrijednosti ne mogu se koristiti u stupcu identiteta. Mora biti navedeno kao početna vrijednost, i povećati ili ne specificirati ništa. Ako nije navedena nijedna vrijednost, zadana vrijednost je (1,1).

Sintaksa:

[IDENTITET [(sjeme, prirast)]

seed - vrijednost koja se koristi za prvi redak učitan u tablicu.

inkrement - s vrijednost prirasta za dodavanje prethodno učitanoj vrijednosti identifikatora retka.

[ Raspored soba] INT IDENTITET (1, 1) NIJE NULL PRIMARNI KLJUČ

    Izračunata polja.

Sintaksa:

<имя_столбца> KAO <выражение> ]

Izraz koji specificira vrijednost izračunatog stupca. Izračunati stupac je virtualni stupac koji nije fizički pohranjen u tablici osim ako za njega nije postavljena zastavica PERSISTED. Vrijednost stupca izračunava se na temelju izraza koji koristi druge stupce u istoj tablici.

Na primjer, izračunata definicija stupca može biti sljedeća:

Trošak robe KAO Cijena za jedan * Količina.

Izraz može biti ne-izračunato ime stupca, konstanta, funkcija, varijabla ili bilo koja njihova kombinacija, povezana s jednim ili više operatora. Izraz ne može biti podupit niti sadržavati pseudonime tipa podataka.

Izračunati stupci mogu se koristiti u odabranim popisima, WHERE klauzulama, ORDER BY klauzulama i bilo gdje drugdje gdje se mogu koristiti regularni izrazi, osim u sljedećim slučajevima.

Izračunati stupac ne može se koristiti kao definicija ograničenja DEFAULT ili FOREIGN KEY, ili u kombinaciji s NOT NULL definicijom ograničenja. Međutim, izračunati stupac može se koristiti kao stupac ključnog indeksa ili kao dio ograničenja PRIMARY KEY ili UNIQUE ako je vrijednost izračunatog stupca određena determinističkim (predvidljivim) izrazom, a tip podataka rezultata dopušten je u stupcima indeksa .

Na primjer, ako tablica sadrži cjelobrojne stupce a i b, izračunati stupac a + b može se uključiti u indeks i izračunati stupac a + DATEPART (dd, GETDATE ())- ne može, jer se njegova vrijednost može promijeniti u sljedećim pozivima.

Izračunati stupac ne može biti ciljni stupac INSERT ili UPDATE izraza.

DBMS automatski određuje nullability za izračunate stupce na temelju korištenih izraza. Pretpostavlja se da je rezultat većine izraza nullable, čak i ako se koriste samo stupci koji nisu nullable, budući da moguće prekoračenje ili gubitak preciznosti može rezultirati null vrijednosti. Da biste saznali može li izračunati stupac tablice biti null, upotrijebite funkciju COLUMNPROPERTY sa svojstvom AllowsNull... Uvjerite se da izraz ne dopušta nulte vrijednosti, možete tako da navedete ISNULL s konstantom provjera_izraz gdje je konstanta vrijednost različita od nule, koja zamjenjuje bilo koju vrijednost NULL. Izračunati stupci temeljeni na izrazu koji sadrže CLR UDT zahtijevaju dopuštenje REFERENCES za tip.

Označava da komponenta SQL Server fizički će pohraniti izračunate vrijednosti u tablicu i ažurirati ih kad god se promijeni bilo koji stupac o kojem izračunati stupac ovisi. Navođenje PERSISTED na izračunatom stupcu omogućuje vam stvaranje indeksa na izračunatom stupcu koji je deterministički, ali neprecizan.

Na stvaranje tablice Kao dodatak tehnikama o kojima se raspravlja, možete specificirati izbornu ključnu riječ CONSTRAINT kako biste ograničenju dali ime koje je jedinstveno unutar baze podataka.

STVORITI T SPOSOBNA Narudžbe(

ID_NarudžbaINT NIJE NULL ,

Jelo INT NIJE NULL,

Količina_ porcije INT NOT NULL CHECK ( Količina_ porcije >0 ) ,

datum DATUM NIJE NULL ,

GLAVNI KLJUČ ( ID_Narudžba, Jelo, datum),

OGRANIČENJE STRANI KLJUC

STRANI KLJUC ( Jelo, datum) REFERENCE izbornik( Jelo, datum)) ;

Tada možete raditi s imenovanim ograničenjem kao s objektom baze podataka. Ako naziv ograničenja nije specificiran, DBMS motor će ga automatski kreirati, birajući naziv prema pravilima definiranim u sustavu.

Primjer skripte koju je izradio sustav za stvaranje tablice Dish_view_view

STVORI TABLICU. [referenca za vrstu jela] (

IDENTITET (1,1) NIJE NULL,

[Prikaz] (20) NIJE NULL,

OGRANIČENJE PRIMARNI KLJUČ SKUPAN

) SA (PAD_INDEX = ISKLJUČENO, STATISTICS_NORECOMPUTE = ISKLJUČENO, IGNORE_DUP_KEY = ISKLJUČENO, ALLOW_ROW_LOCKS = UKLJUČENO, ALLOW_PAGE_LOCKS = UKLJUČENO)

Vidjeli ste neke od konfiguracijskih konvencija koje koristi ovaj pristup. Konkretno, vidjeli ste kako prilagoditi model entiteta koristeći bilješke podataka izražene kroz atribute C # i korištenjem Fluent API-ja. U ovom i sljedećim člancima pobliže ćemo pogledati ove načine prilagođavanja modela podataka.

Prilagođavanje vrsta stupaca

Ranije, kada ste pogledali slučaj upotrebe Code-First, već ste vidjeli upotrebu nekih atributa metapodataka koji su vam omogućili da prilagodite tip podataka stupca u tablici baze podataka i na njega primijenite ograničenja (na primjer, navođenjem je li podržava nulte vrijednosti). U nastavku ćemo detaljnije pogledati ove atribute.

Ograničenje duljine

Tablica u nastavku prikazuje konvencije za ograničavanje duljine stupaca, kako su označene i implementirane u Fluent API-ju:

Ograničenje duljine može se nametnuti nizovima ili nizovima bajtova. Po konvenciji, Code-First koristi samo ograničenje maksimalne duljine, što znači da SQL Server postavlja tip podataka za nizove i nizove bajtova na NVARCHAR (n) i VARBINARY (n), gdje je n duljina navedena u ograničenju. Prema zadanim postavkama, ako na svojstva modela nije primijenjeno ograničenje duljine, Code-First će postaviti maksimalnu moguću duljinu stupaca na NVARCHAR (max) i VARBINARY (max).

Kao što je prikazano u tablici, pomoću bilješki podataka možete postaviti minimalnu duljinu za svojstvo modela pomoću atributa MinLength - ovo ograničenje ni na koji način neće utjecati na tablicu baze podataka. (Kao što je ranije opisano, atributi metapodataka mogu se koristiti ne samo u Entity Frameworku, već, na primjer, i u validaciji ASP.NET modela.) Zato metoda HasMinLength () nedostaje u Fluent API-ju, budući da ovaj API dio je Entity Frameworka i odgovoran je za postavljanje konvencija samo za kodiranje.

Vrijedi napomenuti da možete odrediti maksimalnu i minimalnu duljinu polja u jednom StringLength atributu koristeći imenovane parametre ovog atributa. V sljedeći primjer pokazuje upotrebu ograničenja duljine pomoću napomena (ovdje koristimo primjer modela koji smo kreirali u prethodnom članku “Using Code-First”):

Korištenje sustava; koristeći System.Collections.Generic; korištenjem System.ComponentModel.DataAnnotations; imenski prostor CodeFirst (javna klasa Customer (public int CustomerId (get; set;) public string FirstName (get; set;) public string LastName (get; set;) public string Email (get; set;) public int Age (get; set;) ;) javni bajt Fotografija (dobi; postavi;) // Veza na javni virtualni popis naloga Narudžbe (get; set;)) javna klasa Order (public int OrderId (get; set;) public string ProductName (get; set;) public string Opis (get; set;) public int Quantity (get; set;) public DateTime PurchaseDate (get; set;) // Veza na kupca javnog kupca Kupac (get; set;)))

I u sljedećem kodu slična postavka se radi pomoću Fluent API-ja (zapamtite da za korištenje ovog API-ja morate nadjačati metodu konfiguracije OnModelCreating () u klasi konteksta, što je u našem primjeru klasa SampleContext):

() .Svojstvo (c => c.FirstName) .HasMaxLength (30); modelBuilder.Entitet () .Svojstvo (c => c.Email) .HasMaxLength (100); modelBuilder.Entitet () .Property (o => o.ProductName) .HasMaxLength (500); )

Eksplicitno navođenje vrste stupca

Kao što je ranije opisano, Entity Framework automatski preslikava tipove podataka modela u tipove podataka usklađene sa SQL-om. Code-First vam omogućuje da manipulirate ovim procesom kako biste eksplicitno naveli vrstu podataka za stupac, kao što je prikazano u primjeru u nastavku:

Public class Customer (public int CustomerId (get; set;) // ... javni bajt Photo (get; set;) // ...) // isto sa Fluent API zaštićenim nadjačavanjem void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder. Entitet () .Property (c => c.CustomerId) .HasColumnType ("smallint"); modelBuilder.Entitet () .Svojstvo (c => c.Fotografija) .HasColumnType ("slika"); )

Podrška za stupac NULL

Konvencija Entity Framework Null Support na stupcu tablice navodi da se svi .NET tipovi koji podržavaju null vrijednosti (objekti) mapiraju u SQL tipove eksplicitno nullable, i obrnuto, .NET tipovi koji ne podržavaju null (strukture) mapiraju se u SQL tipovi s eksplicitnim NOT NULL izrazom.

Da biste eksplicitno naznačili da tip podataka ne bi trebao podržavati null vrijednosti, morate koristiti atribut Required na modelu podataka ili koristiti IsRequired () metodu konfiguracijskog objekta u Fluent API-ju. Da biste eksplicitno naznačili naprotiv da tip podataka treba podržavati NULL vrijednosti, trebate koristiti zbirku Nullable ili koristite C # sintaksu, koja za tipove vrijednosti koje podržavaju null uključuje upitnik nakon te vrste (na primjer, int?).

Primjer u nastavku pokazuje kako upotrijebiti ove postavke za konfiguriranje informacija o tipovima koji se mogu null ili koji nisu null u tablici baze podataka:

Javna klasa Customer (public int CustomerId (get; set;) public string FirstName (get; set;) public string LastName (get; set;) // Ovo polje može biti NULL, // budući da smo eksplicitno naveli tip int? public int? Dob (get; set;) // Slično prethodnom svojstvu public Nullable Age1 (get; set;) // ...) // isto sa Fluent API zaštićenim nadjačavanjem void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.Entity () .Svojstvo (c => c.Ime) .Je potrebno (); modelBuilder.Entitet () .Svojstvo (c => c.Prezime) .Je potrebno (); )

Imajte na umu da se samo NOT NULL podrška za referentne tipove podataka može konfigurirati u Fluent API-ju, a NULL podrška se ne može konfigurirati za vrste vrijednosti, budući da NULL podrška za njih je eksplicitno navedena kada se deklarira tip svojstva u klasi modela.

Postavljanje primarnih ključeva

Entity Framework zahtijeva da svaka klasa modela entiteta ima jedinstveni ključ (jer za svaku tablicu u relacijske baze podataka, mora se koristiti primarni ključ). Ovaj se ključ koristi u objektu konteksta za praćenje promjena u objektima modela. Code-First daje neke pretpostavke kada traži ključ u tablici. Na primjer, kada smo ranije generirali bazu podataka za klase entiteta Customer i Order, gledajući pristup Code-First, Entity Framework je označio polja CustomerId i OrderId u tablicama kao primarne ključeve i postavio ih da podržavaju tipove koji nisu null :

EF je također automatski dodao podršku za automatsko povećanje ovim poljima (zapamtite da se u T-SQL-u to radi pomoću izraza IDENTITY). Najčešće su primarni ključevi u bazi podataka tipa INT ili GUID, iako ih ima primitivni tip može se koristiti kao primarni ključ. Primarni ključ u bazi podataka može se sastojati od više stupaca tablice, slično, ključ modela EF entiteta može biti sastavljen od više svojstava modela. Kasnije ćete vidjeti kako postaviti složene tipke.

Eksplicitno postavljanje primarnih ključeva

U slučaju naše dvije klase, Customer i Order, nema potrebe brinuti se o eksplicitnom navođenju primarnog ključa, budući da koristimo svojstva CustomerId i OrderId, koja slijede konvenciju imenovanja ključa "+ Id". Pogledajmo primjer gdje trebate eksplicitno navesti primarni ključ. Dodajte sljedeću jednostavnu klasu u svoju datoteku modela:

Projekt javne klase (javni Guid Identifier (get; set;) public DateTime StartDate (get; set;) public DateTime EndDate (get; set;) javni decimalni trošak (get; set;))

Naš cilj je ukazati da je svojstvo Identifier u ovoj klasi primarni ključ tablice. Kao što možete vidjeti, naziv ovog svojstva ne slijedi konvenciju imenovanja primarnog ključa Entity Framework.

Dodajte opis nove tablice u klasu konteksta SampleContext:

Javna klasa SampleContext: DbContext (// ... javni DbSet Projekti (dobi; postavi;) // ...)

Sada, ako pokrenete našu aplikaciju i umetnete podatke novog kupca, iznimka će biti ubačena u klasu DbModelBuilder, zbog činjenice da ne može ispravno izgraditi model podataka entiteta. (Podsjetimo, naša je aplikacija jednostavna ASP.NET stranica s mogućnošću umetanja novog korisnika.)

Ova iznimka je uzrokovana time što Entity Framework ne nalazi svojstvo pod nazivom Id ili ProjectId u tablici projekta, a Code-First ne može shvatiti koje polje koristiti kao primarni ključ tablice. Ovaj se problem može ispraviti korištenjem napomena podataka ili Fluent API-ja, kao što je prikazano u primjeru u nastavku:

Projekt javne klase (javni Guid Identifier (get; set;) public DateTime StartDate (get; set;) public DateTime EndDate (get; set;) javni decimalni trošak (get; set;)) // isto s Fluent API zaštićenim nadjačavanjem void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.Entity () .HasKey (p => p.Identifier); )

Imajte na umu da kada koristite Fluent API metoda HasKey () je specificiran nakon poziva metode Entity () a ne nakon poziva entiteta () .Svojstvo (), kao što je učinjeno u gornjim primjerima, budući da primarni ključ je postavljen na razini tablice, a ne na razini svojstva.

Postavljanje autoinkrementa za primarne ključeve

Kao što možete vidjeti iz tablice, slijedeći konvencije, Entity Framework specificira automatsko povećanje za int svojstva. U prethodno kreiranoj tablici projekta, tip Guid je specificiran za primarni ključ, zbog čega EF ne koristi brojač za ovo polje prilikom kreiranja tablice u bazi podataka. To je prikazano na slici:

Dodajmo novi web obrazac našem projektu, koji ćemo nazvati DatabaseGenerated.aspx. U rukovatelju Page_Load dodajte sljedeći kod gdje dodajemo nove podatke u tablicu projekta. V u ovom slučaju ovi će podaci biti dodani svaki put kada otvorimo stranicu našeg web obrasca u pregledniku.

Korištenje sustava; korištenje System.Data.Entity; koristeći CodeFirst; imenski prostor ProfessorWeb.EntityFramework (javna djelomična klasa DatabaseGenerated: System.Web.UI.Page (zaštićena void Page_Load (pošiljatelj objekta, EventArgs e) (// Ova postavka je potrebna kako bi se baza podataka automatski // obrisala i ponovno kreirala kada struktura je promijenjena modeli // (radi lakšeg testiranja primjera) Database.SetInitializer (novi DropCreateDatabaseIfModelChanges ()); SampleContext kontekst = novi SampleContext (); Projektni projekt = novi projekt (Datum početka = Datum Vrijeme. Sada, Krajnji Datum = Datum Vrijeme. Sada. DodajMjeseci (1), Trošak = 8000M); kontekst.Projekti.Dodaj (projekt); context.SaveChanges (); )))

Pokrenite projekt i otvorite web obrazac DatabaseGenerated.aspx. Kao rezultat toga, novi zapis bit će dodan u tablicu projekta:

Ni baza podataka ni Entity Framework ne znaju da bismo željeli stvoriti novi Guid za svaki novi zapis, pa će se ID koji sadrži sve nule automatski generirati. Ako osvježite stranicu u pregledniku (zapravo, u ovom slučaju, kôd će pokušati umetnuti novi unos u tablicu), tada će Entity Framework vratiti SqlException, koji je izbačen jer pokušavamo umetnuti zapis s identifikatorom koji već postoji u tablici, tj. u ovom slučaju se aktivira ograničenje primarnog ključa - mora biti jedinstveno za svaki novi zapis.

Kao rezultat toga, odlučiti ovaj problem, trebali bismo generirati jedinstveni Guid u kodu. Tablice koje koriste automatsko povećanje za primarne ključeve nemaju ovaj dodatni posao. za svaki novi umetnuti zapis, brojač stvara novu vrijednost za primarni ključ dohvaćanjem vrijednosti primarnog ključa za zadnji zapis i dodavanjem 1 na njega (ako je korišten IDENTITY (1,1)).

Da biste riješili ovaj problem za ključeve vrste različitog od int, morate koristiti DatabaseGenerated metapodatki atribut u čijem konstruktoru navedete DatabaseGeneratedOption nabrajanje imajući tri moguća značenja:

Nijedan

Baza podataka ne generira nikakvu jedinstvenu vrijednost za primarni ključ. Zapravo, pomoću ove opcije možete onemogućiti automatsko dodavanje automatskog povećanja primarnim ključevima tipa int.

Identitet

Prilikom umetanja vrijednosti u tablicu, kreirat će se baza podataka jedinstvena vrijednost za primarni ključ.

Izračunati

Slično kao Identity, s jedinom iznimkom da će se primarni ključ generirati ne samo kada umetnete zapise u tablicu, već i kada se ažuriraju.

Izmijenite klasu modela kako biste naložili bazi podataka da stvori jedinstveni primarni ključ:

Projekt javne klase (javni Guid Identifier (get; set;) public DateTime StartDate (get; set;) public DateTime EndDate (get; set;) javni decimalni trošak (get; set;))

Pokrenite ogledni projekt i nekoliko puta osvježite stranicu kako biste umetnuli više zapisa u tablicu i osigurali da se iznimka više ne javlja. Slika ispod prikazuje podatke dodane u tablicu:

Obratite pažnju na automatski generirane ID-ove za projekte. Isti učinak može se postići korištenjem metode HasDatabaseGeneratedOption () u Fluent API-ju:

Zaštićeno nadjačavanje void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.Entity () .Svojstvo (p => p.Identifier) ​​.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity); )

Rad sa složenim tipovima podataka

Entity Framework podržava mogućnost korištenja složenih tipova od prve verzije. Zapravo, složeni tip u .NET-u je klasa koja se može referencirati u klasi modela. Složeni tip nema ključ i može se koristiti na više objekata u modelu. Uzmimo primjer sljedećeg modela:

Public class User (javni int UserId (get; set;) public int SocialNumber (get; set;) public string FirstName (get; set;) public string LastName (get; set;) public string StreetAddress (get; set;) public string Grad (dobi; postavi;) javni niz ZipCode (dobi; postavi;))

U ovoj klasi se može razlikovati adresa prebivališta korisnika odvojeni razred i da se pozivam na to:

Javna klasa Korisnik (public int UserId (get; set;) public int SocialNumber (get; set;) public string FirstName (get; set;) public string Prezime (get; set;) Public Address Address (get; set;)) javna klasa Address (public int AddressId (get; set;) public string StreetAddress (get; set;) public string City (get; set;) public string ZipCode (get; set;))

Po konvenciji, Entite Framework će analizirati ovaj model kao dvije odvojene tablice. Ali naš cilj je stvoriti složeni tip iz klase Address. Tradicionalni način za stvaranje složenog tipa iz klase Address uvodi se uklanjanje AddressId-a:

Public class Address (// public int AddressId (get; set;) public string StreetAddress (get; set;) public string City (get; set;) public string ZipCode (get; set;))

Uz pravilo da složeni tip ne smije imati ključ, Code-First nameće još dva pravila koja se moraju poštivati ​​da bi se otkrio složeni tip. Prvo, složeni tip bi trebao sadržavati samo jednostavna svojstva. Drugo, klasi koja koristi ovaj tip nije dopušteno specificirati tip zbirke za svojstvo složenog tipa. Drugim riječima, ako želite koristiti složeni tip Address u klasi User, tada svojstvo ove vrste ne bi trebalo biti označeno kao List

ili koristite drugu kolekciju.

Kao što je prikazano na donjoj slici, nakon pokretanja aplikacije, Code-First prepoznaje složeni tip i stvara prilagođena polja u tablici korisnika (ne zaboravite dodati deklaraciju korisnika u klasu konteksta):

Imajte na umu kako se polja koja opisuju adresu korisnika nazivaju: ComplexTypeName_PropertyName. Ovo je konvencija imenovanja Entity Framework za složene tipove.

Prilagodba složenih tipova zaobilazeći konvencije prvog koda

Što ako vaša složena klasa tipa ne slijedi konvencije Entity Frameworka, na primjer, želite koristiti polje AddressId u klasi Address? Ako sada dodamo ovo polje u klasu Address i pokrenemo projekt, tada će umjesto jedne korisničke tablice i složenog tipa adrese, Entity Framework kreirati dvije tablice koje su međusobno povezane stranim ključem. Da biste riješili ovaj problem, možete izričito navesti Atribut ComplexType u klasi modela ili upotrebi ComplexType () metoda klasa DbModelBuilder u Fluent API-ju:

Adresa javne klase (public int AddressId (get; set;) public string StreetAddress (get; set;) public string City (get; set;) public string ZipCode (get; set;)) // isto sa Fluent API zaštićenim nadjačavanjem void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.ComplexType

(); }

Gore je rečeno da klasa koja opisuje složeni tip treba imati samo jednostavna svojstva (tj. ne odnositi se na druge objekte). Ovaj sporazum se može prevladati korištenjem svih istih sredstava. Ispod je primjer u kojem je dodan novi složeni tip UserInfo koji upućuje na drugu vrstu punog imena:

Javna klasa User (javni int UserId (get; set;) public UserInfo UserInfo (get; set;) javna adresa adrese (get; set;)) javna klasa UserInfo (public int SocialNumber (get; set;) // Nije jednostavno svojstvo public FullName FullName (get; set;)) public class FullName (javni string FirstName (get; set;) public string Prezime (get; set;)) public class Address (public int AddressId (get; set;) public string StreetAddress ( dobiti; postaviti;) javni niz Grad (dobiti; postaviti;) javni niz poštanski broj (dobiti; postaviti;))

Uputivši Code-First da je UserInfo složen tip pomoću atributa ComplexType, prevladali smo ograničenje složenih tipova korištenjem zadane konvencije.

Vrijedi napomenuti da vam Code-First omogućuje prilagođavanje složenih tipova baš kao i obične tablice pomoću Fluent API-ja ili bilješki. U nastavku je primjer za postavljanje adrese složenog tipa:

Adresa javne klase (public int AddressId (get; set;) public string StreetAddress (get; set;) public string City (get; set;) public string ZipCode (get; set;)) // isto sa Fluent API zaštićenim nadjačavanjem void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.ComplexType

() .Svojstvo (a => a.Adresa ulice) .HasMaxLength (100); )

Slika ispod prikazuje strukturu korisničke tablice. Ovdje možete vidjeti kako EF imenuje svojstva složenih tipova s ​​referencama unutar i kako EF nameće ograničenje na polje StreetAddress:

Opis ostalih postavki

U ovom ćemo odjeljku ukratko pregledati sve preostale postavke stupaca tablice, koje se zbog svojih specifičnih značajki rijetko koriste.

Stupci vremenske oznake

Tip podataka TIMESTAMP u T-SQL specificira stupac koji je definiran kao VARBINARY (8) ili BINARY (8), ovisno o svojstvu stupca, da bude NULL. Za svaku bazu podataka, sustav sadrži brojač koji se povećava svaki put kada se umetne ili ažurira bilo koji red koji sadrži TIMESTAMP ćeliju i dodjeljuje toj ćeliji zadanu vrijednost... Dakle, pomoću ćelija tipa TIMESTAMP, možete odrediti relativno vrijeme Posljednja promjena odgovarajućim redovima tablice. (ROWVERSION je sinonim za TIMESTAMP.)

Sama po sebi, vrijednost pohranjena u stupcu TIMESTAMP nije važna. Ovaj se stupac obično koristi za određivanje je li se određeni red u tablici promijenio od posljednjeg pristupa. To omogućuje adresiranje istodobnog pristupa tablici baze podataka dopuštajući drugim nitima da blokiraju ako je trenutna nit promijenila vrijednosti u nizu.

U Code-First, da bi se naznačilo da stupac treba biti tipa TIMESTAMP, treba koristiti isto ime Atribut vremenske oznake u napomenama ili Metoda IsRowVersion (). u Fluent API-ju kao što je prikazano u primjeru u nastavku:

Javni bajt RowVersion (get; set;) // isto sa Fluent API zaštićenim nadjačavanjem void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.Entity () .Svojstvo (p => p.RowVersion) .IsRowVersion (); )

Manje uobičajen način da budete sigurni kada radite s paralelnim nitima je specificiranje provjere istodobnosti za svaki stupac. Ova se metoda još uvijek može koristiti u DBMS-ovima koji ne podržavaju tipove vremenske oznake/verzije reda. Kada radi na ovaj način, nit ne provjerava je li se zapis u tablici promijenio, već jednostavno blokira pristup njemu za druge niti dok ne završi proces pisanja. Da biste naveli stupce koji će proći provjeru istodobnosti, koristite Atribut ConcurrencyCheck u bilješkama, ili Metoda IsConcurrencyToken (). u Fluent API-ju.

Promjena kodiranja niza iz Unicodea u ASCII

Prema zadanim postavkama, Entity Framework će sve pretvoriti vrste nizova model podataka kao što su string ili char u SQL nizove tipova podataka koji koriste dvobajtno Unicode kodiranje NVARCHAR ili NCHAR. Možete promijeniti ovo ponašanje da eksplicitno kažete EF-u da koristi jednobajtno ASCII kodiranje - VARCHAR i CHAR će se koristiti u skladu s tim. Da biste to učinili, morate koristiti Metoda IsUnicode (). s logičkim parametrom koji mu je proslijeđen u Fluent API-ju. Bilješke ne pružaju mogućnost prilagođavanja kodiranja nizova.

Određivanje preciznosti za decimalni tip

Možeš koristiti Metoda HasPrecision (). s dva parametra koja su mu proslijeđena, što se koristi u Fluent API-ju. Bilješke podataka u Code-First ne nude alternativu ovoj metodi. Prema zadanim postavkama, Entity Framework postavlja preciznost na 18 i skalu na 2 za decimalne vrste.

Primjer u nastavku pokazuje upotrebu ove metode za svojstvo Cost tablice projekta koju smo ranije kreirali gledajući primarne ključeve:

Zaštićeno nadjačavanje void OnModelCreating (DbModelBuilder modelBuilder) (modelBuilder.Entity () .Svojstvo (p => p.Cost) .HasPrecision (6, 3); )

Što je IDENTITET

IDENTITY nije vrsta podataka. Ovo je neko dodatno svojstvo, ograničenje nametnuto na cjelobrojne tipove podataka u MS SQL Serveru. Oni. ovo svojstvo može se primijeniti na polja sljedećih tipova: tinyint, smallint, int, bigint, decimalni (p, 0), ili numerički (p, 0)

FoxPro analog ovog svojstva je tip podataka Integer-AutoIncrement. Samo nemojte pretpostavljati da je Integer-AutoIncrement polje sa svojstvom Identity. Nikako. Ovo je upravo analog. Uglavnom su slični, ali imaju niz razlika. Ovaj će se članak usredotočiti na svojstvo IDENTITY u MS SQL poslužitelju.

Polja sa svojstvom IDENTITY imaju sljedeće značajke:

  • Samo jedno polje sa svojstvom IDENTITY može postojati u jednoj tablici.
  • Polje sa svojstvom IDENTITY ne može se uređivati. Oni su samo za čitanje.
  • Vrijednost za polje sa svojstvom IDENTITY dodjeljuje se automatski kada se kreira novi zapis.

Postoje još neke značajke, ali one su već posljedica navedenih značajki.

Nova vrijednost je posljednja korištena vrijednost plus neka fiksna vrijednost. Imajte na umu da se nova vrijednost ne temelji na maksimalnoj vrijednosti u postojeće evidencije, i po posljednjoj korištenoj vrijednosti. To znači da zapisi s posljednjom korištenom vrijednošću možda fizički ne postoje, ali će se ova vrijednost koristiti.

Drugim riječima, rupe u slijedu vrijednosti polja sa svojstvom IDENTITY savršeno su prihvatljive. Popis značenja uopće nije kontinuiran

Obično je 1 navedeno kao prirast, ali može biti bilo koji cijeli broj. Uključujući negativne.

Zbog ove prirode polja sa svojstvom IDENTITY, takva se polja često koriste kao primarni ključevi. Drugim riječima, kao polja, po čijoj vrijednosti uvijek možete jednoznačno identificirati zapis tablice.

Imajte na umu da svojstvo IDENTITY nema kontrolu nad jedinstvenošću podataka. Na primjer, ako je polje izvorno bilo tipa INTEGER i u njega je uneseno više vrijednosti. A onda je struktura tablice promijenjena, a svojstvo IDENTITY je nametnuto ovom polju, tada novi zapisi mogu imati iste podatke koji su već uneseni ranije u ovu tablicu. Stoga, ako se polje sa svojstvom IDENTITY koristi kao primarni ključ, tada bi ovom polju trebalo nametnuti dodatno ograničenje jedinstvenosti.

Nedostatak korištenja polja sa svojstvom IDENTITY kao primarnim ključem

Međutim, unatoč jasnim prednostima korištenja polja sa svojstvom IDENTITY kao primarnim ključem, ona također imaju ozbiljan nedostatak.

Vrijednost polja sa svojstvom IDENTITY ne može se znati dok se zapis fizički ne kreira.

Pa što? Koji su problemi? Napravimo zapis i saznajmo njegovu novu vrijednost.

Problem je u tome što da bi se saznala vrijednost polja bilo kojeg zapisa, najprije se mora pronaći ovaj zapis. A potraga za zapisom upravo se provodi po vrijednosti primarnog ključa. Onaj čije se značenje mora utvrditi. Začarani krug: da biste pročitali vrijednost, morate znati ovu vrijednost!

Struktura pohrane podataka u MS SQL poslužitelju bitno se razlikuje od strukture pohrane podataka u DBF datotekama. Ne sadrži pojmove kao što su " fizički broj zapisi "," sljedeći zapis "," zadnji zapis ", itd. To jest, nemoguće je prijeći na" zadnji zapis "da biste pročitali vrijednost njegovog primarnog ključa.

Štoviše, iako je nova vrijednost polja sa svojstvom IDENTITY uvijek veća od bilo koje postojeće vrijednosti(ako je prirast pozitivan broj), ali je također nemoguće odrediti ovu novu vrijednost jednostavnim izračunavanjem maksimuma postojećih vrijednosti. Ne, sama maksimalna vrijednost će se, naravno, dobiti. Jednostavno ne postoji jamstvo da je rezultirajuća vrijednost vrijednost točnog zapisa koji je stvoren.

Poanta je da se, u pravilu, MS SQL poslužitelj koristi u višekorisničkim aplikacijama. To znači da nekoliko korisnika odjednom može kreirati nove zapise u isto vrijeme. Ispada da je jedan korisnik kreirao novi zapis, zatim počeo računati maksimalnu vrijednost, a u tom trenutku je drugi korisnik također kreirao novi zapis. Kao rezultat toga, prvi korisnik kao maksimalna vrijednost dobit će vrijednost unosa koji je kreirao drugi korisnik.

Dakle, trebamo li prestati koristiti polja sa svojstvom IDENTITY kao primarnim ključem? Nikako. Ipak, postoje načini za određivanje vrijednosti polja sa svojstvom IDENTITY novog zapisa.

Kako odrediti vrijednost polja sa svojstvom IDENTITY u novom zapisu

Zapravo, postoje tri temeljne strategije za određivanje vrijednosti polja sa svojstvom IDENTITY u novom, upravo stvorenom, zapisu

Pogledajmo sada pobliže prednosti i nedostatke svake strategije.

Vrijednost koju vraća varijabla sustava @@ IDENTITY

U MS SQL poslužitelju postoji niz sistemskih varijabli čija se vrijednost automatski mijenja kada se dogode određeni događaji. Konkretno, varijabla sustava @@ IDENTITY automatski se postavlja na vrijednost polja IDENTITY posljednjeg kreiranog zapisa u trenutnoj vezi. Oni. stvaranje novih zapisa u drugoj vezi (od strane drugog korisnika) ni na koji način neće utjecati na njegovu vrijednost u ovoj vezi.

Pa to je to, rješenje. Jednostavno nakon kreiranja novog zapisa čitamo vrijednost sistemske varijable @@ IDENTITY i imamo željenu vrijednost.

U cjelini, istina je. Jedini problem je što varijabla sustava @@ IDENTITY mijenja svoju vrijednost kada se u njoj kreira zapis bilo koji stol.

U praksi to znači da ako je okidač za umetanje postavljen na tablicu, u čijem se tijelu daje naredba INSERT za kreiranje zapisa u drugoj tablici, koja zauzvrat također ima polje sa svojstvom IDENTITY, tada @@ Sistemska varijabla IDENTITY će primiti vrijednost polja iz ove druge tablice.

Drugim riječima, možete se osloniti na vrijednost varijable sustava @@ IDENTITY, ali zapamtite da ova varijabla nije vezana za vrijednost polja u jednoj tablici.

Vrijednost koju vraća funkcija SCOPE_IDENTITY ().

Predstavljena verzija MS SQL 2000 funkcija sustava SCOPE_IDENTITY (). Ova funkcija također vraća vrijednost polja sa svojstvom IDENTITY posljednjeg kreiranog zapisa, ali stvorenog unutar trenutnog SCOPE.

Prilično je teško adekvatno prevesti pojam SCOPE na ruski. Ali, otprilike, možete reći ovo: SCOPE je jedan postupak ili funkcija. Drugim riječima, SCOPE_IDENTITY () će vratiti vrijednost polja sa svojstvom IDENTITY posljednjeg zapisa kreiranog unutar procedure u kojoj je ova funkcija pozvana.

Okidač je drugačiji SCOPE (druga funkcija), tako da neće utjecati na povratnu vrijednost SCOPE_IDENTITY () ni na koji način.

Čak i ako su dva korisnika pozvala isti postupak u isto vrijeme, ali svaki je pozvao proceduru u svom SCOPE. Oni. opet nema sukoba.

Nedostaci ove funkcije su što je treba pozvati unutar SCOPE-a, gdje je kreiran novi zapis tablice koja nas zanima. A to nije uvijek moguće.

Drugim riječima, da biste ispravno koristili SCOPE_IDENTITY (), uvijek morate pratiti opseg SCOPE. Često stvaranjem posebnih postupaka.

Pronalaženje novog zapisa prema vrijednosti drugih polja

Ako se sjećate, glavni problem s definiranjem vrijednosti polja sa svojstvom IDENTITY je taj što se ovo polje koristi kao primarni ključ. Oni. po njegovoj vrijednosti se pronalazi traženi zapis.

Međutim, često tablice imaju polje ili skup polja pomoću kojih se zapis također može jedinstveno identificirati. Na primjer, ako dolazi o imeniku, tada, naravno, imenik ima polje "Naziv". Također je očito da ovo polje mora biti jedinstveno unutar imenika. Inače se jednostavno gubi smisao korištenja same priručnika. Zašto unositi zapise sa istu vrijednost?

Zašto ne koristite ovo "Ime" kao primarni ključ? Zašto vam je uopće potrebno polje sa svojstvom IDENTITY? Ovo je tema za drugi razgovor. Ukratko, "Title" je za korisnika (vanjski podaci), a IDENTITY je za osiguranje referentnog integriteta baze podataka (interni podaci).

Vrijednost polja sa svojstvom IDENTITY u novom zapisu nije poznata. Ali značenje polja "Naslov" u ovom novom zapisu je dobro poznato. Korisnik ga je sam unio! To znači da nakon kreiranja novog zapisa možete pronaći ovaj novi zapis po vrijednosti polja "Naziv" i pročitati vrijednost polja sa svojstvom IDENTITY.

Jedini problem je što takvo polje ili skup polja ne postoji uvijek za jedinstvenu identifikaciju zapisa. Inače, to je jedan od razloga za unos takozvanih surogat ključeva. Ta ista polja sa svojstvom IDENTITY.

Ako ipak odlučite koristiti ovu strategiju za pronalaženje novog zapisa, svakako nametnite jedinstveno ograničenje na polje "Naziv" (ili skup polja koji ste odabrali). Odnosno, tako da u ovom polju slučajno ne postoje dva zapisa s istom vrijednošću.

Kako raditi s poljima sa svojstvom IDENTITY u FoxPro-u

Kada je teoretski dio završen, sada "pokušajmo uzletjeti sa svim ovim dobrim." Oni. odlučimo kako iskoristiti sve to znanje u FoxPro-u. Pojasnimo još jednom problem koji treba riješiti.

U tablicu MS SQL poslužitelja dodaje se zapis s poljem sa svojstvom IDENTITY. Potrebno je dobiti vrijednost polja sa svojstvom IDENTITY na strani FoxPro odmah nakon kreiranja novog zapisa.

FoxPro ima tri temeljne opcije za organizaciju rada s MS SQL poslužiteljem

  • Korištenje daljinskog prikaza
  • Korištenje adaptera kursora

Ovdje se trebate zadržati na tome koji događaj zapravo stvara zapis na MS SQL poslužitelju. Pa, s Pass-Troughom je sve jasno. Ovo je zapravo izravna naredba poslužitelju za stvaranje novog zapisa. Ali s daljinskim pogledom i adapterom kursora to je malo drugačije.

Rezultat rada i Remote View i Cursor Adaptera je kursor. Oni. neki privremeni stol koji se fizički nalazi na klijentovom stroju. Prema zadanim postavkama, ovaj kursor se automatski otvara u optimističnom međuspremniku redaka (3) i može se prebaciti samo na optimistično spremanje međuspremnika u tablicu (5). Nemoguće je prebaciti se na pesimistički način rada međuspremnika ili uopće onemogućiti međuspremnik za ovaj kursor.

Posljedično, novi će zapis prvo biti fizički kreiran na klijentskom stroju upravo u ovom kursoru. Točnije, u međuspremniku ovog kursora. Fizičko kreiranje zapisa na MS SQL poslužitelju dogodit će se tek nakon što se međuspremnik isprazni.

Za međuspremnik nizova, međuspremnik se može automatski isprazniti na jedan od sljedećih načina:

  • Preskakanje (ili pokušaj skoka) na drugi zapis
  • Zatvaranje kursora
  • Prelazak na način rada međuspremnika tablice
  • Naredbom TableUpdate ()

Za međuspremnik tablice, međuspremnik se može isprazniti samo naredbom TableUpdate (), a ne drugačije.

Nikakve druge radnje i operacije s daljinskim pogledom ili adapterom kursora neće stvoriti novi zapis na MS SQL poslužitelju. Ako se tijekom izvođenja bilo koje operacije ispostavi da je na MS SQL poslužitelju kreiran novi zapis, to znači da je kursor bio u načinu rada međuspremnika i dogodio se jedan od događaja koji je izazvao automatsko ispiranje međuspremnika.

Na primjer, to se može dogoditi s naredbom Requery () za Remote View. Ali to ne znači da naredba Requery () ispire međuspremnik. Nikako. Samo jedan od uvjeta za izvršenje naredbe Requery () je zatvaranje već postojećeg kursora. Ali ovaj će događaj samo uzrokovati automatsko ispiranje međuspremnika ako je kursor u načinu rada međuspremnika.

Kako biste izbjegli takve nesporazume, prebacite kursor na način rada s međuspremnikom tablice (5). U tom slučaju uvijek možete kontrolirati proces ispiranja međuspremnika.

Međutim, treba imati na umu da čak i ako postavite način rada međuspremnika tablice, promijenite nekoliko zapisa u daljinskom prikazu ili adapteru kursora, a zatim izdate naredbu TableUpdate (), međuspremnik će se i dalje ispirati jedan po jedan zapis. Oni. poslužitelju neće biti poslana niti jedna naredba, na primjer, na izmjenu, već skup naredbi za izmjenu svakog zapisa zasebno.

Što se tiče operacija kreiranja novog zapisa, iz ovoga proizlazi da u svim događajima Adaptera kursora stalno umeće se samo jedan zapis odjednom.

Izravna upotreba Pass-Through tehnologije kroz funkciju SQLEXEC ().

Ovim načinom rada programer radi izravno s MS SQL poslužiteljem. On sam oblikuje sve naredbe poslane poslužitelju, prima rezultat i sam ga obrađuje. U ovom slučaju nije teško poslati dodatni zahtjev poslužitelju za vrijednost funkcije SCOPE_IDENTITY.

LOKALNA lcNewValue, lnResut lcNewValue = "(! LANG: Nova vrijednost" lnResut = SQLExec(m.lnConnectHandle,"INSERT INTO MyTab (Field1) VALUES (?m.lcNewValue)") IF m.lnResut>0 SQLExec(m.lnConnectHandle,"SELECT NewIdent=SCOPE_IDENTITY()","NewIdent") ?NewIdent.NewIdent ELSE LOCAL laError(1) =AERROR(laError) * Анализ массива laError для уточнения причины ошибки ENDIF !}

V ovaj primjer m.lnConnectHandle je broj, broj veze s MS SQL poslužiteljem, koji je ranije konfiguriran. MyTab je tablica koja ima polje sa svojstvom IDENTITY.

Nakon izvršenja drugog upita u rezultirajućem pokazivaču NewIdent u polju NewIdent prvog zapisa i dobiti željenu vrijednost. V zadanu sintaksu i naredba umetanja i poziv funkcije SCOPE_IDENTITY () javljaju se u istom SCOPE-u. Stoga dobivamo željenu vrijednost.

Korištenje daljinskog prikaza

Remote View je svojevrsni "dodatak" tehnologiji Pass-Through. U osnovi, ista naredba INSERT INTO se izvršava prilikom kreiranja novog zapisa. Međutim, problem je u tome što čak i ako pročitate broj veze u kojoj je pokrenut Remote View, a zatim izvršite upit za određivanje vrijednosti koju vraća SCOPE_IDENTITY (), dobit ćemo NULL, jer u ovom slučaju naredba insert i SCOPE_IDENTITY () se izvode u različitim SCOPE-ovima. Stoga postoje samo dva načina za određivanje vrijednosti polja sa svojstvom IDENTITY.

* Određivanje vrijednosti @@ IDENTITY LOCAL varijable sustava lnConnectHandle lnConnectHandle = CursorGetProp ("ConnectHandle", "MyRemoteView") SQLExec (m.lnConnectHandle, "SELECT [e-mail zaštićen]@IDENTITY "," NewIdent ")? NewIdent.NewIdent * Odredite prema vrijednosti drugog polja LOCAL lnConnectHandle, lcNickName lnConnectHandle = CursorGetProp (" ConnectHandle "," MyRemoteView ") lcNickName =Ne MyRemotMeckeView. "," NewIdent ")? NewIdent.TabId

U oba primjera, MyRemoteView je naziv vašeg Remote Viewa. Nadimak je naziv polja u Remote View-u po čijoj se vrijednosti traži novi zapis, a TabID je isto polje sa svojstvom IDENTITY čija se vrijednost mora odrediti

Pretpostavlja se da je kreiranje novog zapisa već došlo. Ili je naredba TableUpdate () eksplicitno dana, ili je udaljeni prikaz u načinu rada u međuspremniku stringova i napravljen je pokušaj navigacije do drugog zapisa.

A zašto u drugom slučaju, čini se, više očito rješenje tražiti nakon Zahtjev ()? Nešto kao

REQUERY ("MyRemoteView") SELECT MyRemoteView LOCATE FOR NickName = "Nova vrijednost"? MyRemoteView.TabID

Postoji nekoliko razloga za to.

Prvo, Requery () pretpostavlja da se upit ponovno izvršava. Oni. pretpostavlja se da je međuspremnik svih zapisa Remote Viewa ispran. Ali ovo možda nije tako. Na primjer, isperite međuspremnik jedan po jedan zapis u petlji.

Drugo, obično Remote View sadrži dodatni uvjeti odabir zapisa, a novonastali zapis možda uopće neće biti uključen u uvjete odabira. Oni. nakon Requery (), zapis, iako će biti fizički kreiran na poslužitelju, neće biti prikazan u samom Remote Viewu.

Korištenje adaptera kursora

Objekt Cursor Adapter uveden je u FoxPro počevši od Visual FoxPro 8. Dizajniran je da olakša rad s udaljenim podacima prilikom izvođenja nekih standardne operacije... Konkretno, operacije stvaranja novog zapisa. Putem Adaptera kursora možete implementirati sve tri opcije za dobivanje vrijednosti polja sa svojstvom IDENTITY u novom zapisu.

Vrijednost koju vraća varijabla sustava @@ IDENTITY

Nakon što se međuspremnik isprazni i novi zapis se fizički kreira na MS SQL poslužitelju, događaj AfterInsert će se pokrenuti u objektu Cursor Adapter. Ovdje u njemu samo trebate napraviti dodatni zahtjev poslužitelju i pročitati vrijednost sistemske varijable @@ IDENTITY

POSTUPAK AfterInsert LPARAMETERS cFldState, lForce, cInsertCmd, lResult IF lResult = .T. && umetanje je uspješno. Morate dobiti ID vrijednost LOCAL currentArea currentArea = SELECT () TRY IF 1 = SQLEXEC (ovaj.DataSource, "SELECT [e-mail zaštićen]@IDENTITY "," NewIdent ") ZAMIJENI TabId SA NewIdent.NewIdent IN (This.Alias) KORISTI U IDRes ELSE LOCAL laError (1) = POGREŠKA (laError) * Analizirajte niz laError kako biste razjasnili uzrok pogreške ENDIF KONAČNO SELECT currentArea) ENDTRY ENDIF ENDPROC

Mislim da je kod dovoljno jasan i ne treba nikakvo objašnjenje. Nakon uspješnog kreiranja novog zapisa na poslužitelju pomoću SQLExec (), vrijednost @@ IDENTITY definirana je za istu vezu i zapisana u trenutni zapis kursora u polju ključa.

U Visual FoxPro 9, svojstvo je dodano objektu Cursor Adapter InsertCmdRefreshCmd... Ovo je naredba koja se šalje poslužitelju tek nakon uspješnog umetanja novog zapisa. Oni. nema potrebe biti uvjeren u samu činjenicu stvaranja nove ploče.

Uparen s još jednom novom nekretninom InsertCmdRefreshFieldList možete lakše nadograditi sa varijable sustava @@ IDENTITY. Da biste to učinili, samo trebate učiniti sljedeće postavke Objekt CursorAdapter

CursorAdapter.InsertCmdRefreshCmd = "SELECT @@ IDENTITY" CursorAdapter.InsertCmdRefreshFieldList = "TabId"

Ovdje TabId nije naziv polja sa svojstvom IDENTITY u tablici na samom MS SQL poslužitelju, već naziv polja kursora primljenog na strani klijenta u kojem se prikazuje sadržaj polja sa svojstvom IDENTITY. U pravilu su ti nazivi isti, ali općenito mogu biti različiti. Saznajte više o nekretnini InsertCmdRefreshFieldList pročitajte u nastavku. U odjeljku o pronalaženju novog zapisa po vrijednosti drugih polja.

Vrijednost koju vraća funkcija SCOPE_IDENTITY ().

Ovdje je sve nešto kompliciranije. Stvar je u tome da ne možete djelovati na isti način kao u slučaju definiranja varijable sustava @@ IDENTITY. SQLExec () i Cursor Adapter rade u različitim OPISIMA. Stoga, s ovim pristupom, SCOPE_IDENTITY () će uvijek vratiti NULL. Za prevladavanje ove kontradikcije koriste se posebni postupci.

Prvo, morate stvoriti takvu pohranjenu proceduru na samom MS SQL poslužitelju

IZRADA POSTUPKA Get_ValueInt @ValueIn Int, @ValueOut Int IZLAZ KAO POSTAVLJENI NOCOUNT NA SELECT @ [e-mail zaštićen]

Kao što možete vidjeti, svrha ovog postupka je jednostavno dodijeliti vrijednost ulaznog parametra izlaznom parametru. Sada možete koristiti ovu proceduru za određivanje vrijednosti SCOPE_IDENTITY () u adapteru kursora. Da biste to učinili, u slučaju Prije umetanja vrši se takva zamjena

POSTUPAK Prije umetanja LPARAMETRI cFldState, lForce, cInsertCmd cInsertCmd = cInsertCmd +; "; DEKLIRATI @id int" +; "; SELECT @ id = SCOPE_IDENTITY ()" +; "; EXEC Get_ValueInt @id, [e-mail zaštićen]"ENDPROC

Samo imajte na umu da u ovoj zamjeni MyTab više nije naziv tablice na MS SQL poslužitelju, već naziv kursora koji je kreirao klijent. Točnije, naziv koji je zabilježen u svojstvu Alias ​​samog adaptera kursora. Prema tome, "TabId" je naziv polja kursora koje je kreirao klijent i koje sadrži vrijednost polja sa svojstvom IDENTITY

U ovom slučaju, u biti, formira se dinamička pohranjena procedura. Oni. ne samo jednu INSERT naredbu, već niz naredbi. Naredbe su odvojene jedna od druge točkom i zarezom, iako to nije potrebno. Dovoljno je odvojiti naredbe jedne od drugih jednostavnim razmakom.

Pronalaženje novog zapisa prema vrijednosti drugih polja

Ako imate Visual FoxPro 8, sve što trebate učiniti je koristiti metodu sličnu metodi koja se koristi za pronalaženje vrijednosti @@ IDENTITY sistemske varijable. Oni. u metodi AfterInsert objekta Adapter kursora, izvršite dodatni zahtjev putem SQLExec ()

Počevši od Visual FoxPro 9, objekt Cursor Adapter ima dodatna svojstva za automatizaciju ovog postupka bez pisanja dodatnog koda.

InsertCmdRefreshFieldList- popis polja čija će vrijednost biti ažurirana nakon umetanja
InsertCmdRefreshKeyFieldList- polje ili skup NE ključnih polja koja također jedinstveno identificiraju zapis, koji će se koristiti za traženje novog zapisa

Treba napomenuti da ova svojstva ne specificiraju nazive polja tablice samog MS SQL poslužitelja, već odgovarajuća imena polja kursora primljena na strani klijenta. Za isti primjer, to bi bilo otprilike ovako:

InsertCmdRefreshFieldList = "TabID" InsertCmdRefreshKeyFieldList = "Nadimak"

Drugim riječima, na temelju vrijednosti polja NickName pronaći će se zapis u tablici na MS SQL poslužitelju i pročitati vrijednost polja TabID, nakon čega će se ta vrijednost upisati u novi zapis na strana klijenta.


Detaljnije, raspravu o ovoj temi i primjere korištenja možete vidjeti ovdje



Vladimir Maksimov
Posljednje ažuriranje: 01.05.06

Vrhunski povezani članci