Jeg satt IDENTITY_INSERT til PÅ, men jeg får en SQLException sier det er OFF

stemmer
2

Jeg prøver å ta tusenvis av fakturaer (og andre ting) fra en tekstfil og sette dem inn i SQL Server 2008. Jeg skrev en liten konsoll app for å gjøre dette, og det bruker LINQ til SQL. Etter at jeg setter alle eksisterende fakturaer Jeg ønsker Invoice_IDå være en identitetskolonne og auto-tilvekst, så jeg har det utformet slik:

CREATE TABLE [dbo].[Invoice]
(
 [Invoice_ID] int IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    /* Other fields elided */
)

Før jeg begynner å sette inn fakturaer jeg kaller en lagret prosedyre som inneholder følgende linje:

SET IDENTITY_INSERT [dbo].[Invoice] ON;
/* Other lines for setup elided */

Etter at jeg har sendt mine endringene jeg ringe en annen lagret prosedyre med følgende linje:

SET IDENTITY_INSERT [dbo].[Invoice] OFF;
/* Other lines for clean up elided */

Når jeg prøver å sette mine fakturaer og sende de endringene jeg får følgende unntak:

SQLException: Kan ikke sette eksplisitt verdi for identitetskolonne i tabell 'Faktura' når IDENTITY_INSERT er satt til AV.

Jeg løp SQL Profiler og jeg kan se at det er faktisk å sette IDENTITY_INSERTONfør du prøver å utføre innleggene. Jeg ser ikke det som blir satt til OFFhvor som helst. Jeg er ganske ny på SQL Profiler, så kanskje det er en hendelse jeg kan aktivere som vil gi meg mer info til prøve og feilsøke dette. Noen ideer?

Jeg har prøvd å tilpasse verdiene i .dbml filen som brukes av LINQ til SQL. Jeg har Invoicetabellens Auto Generated Valuesatt til False, Auto-Syncsatt til Aldri, og Server Data Typesatt til Int NOT NULL. Vanligvis ville jeg ha dem satt til True, On Insert, og Int NOT NULL identitet, henholdsvis, men når jeg gjør jeg kan se at SQL Server er excecuting:

SELECT CONVERT (Int, SCOPE_IDENTITY ()) AS [verdi]

i stedet for å sette inn Invoice_IDdet jeg gi.

Publisert på 29/12/2009 klokken 22:45
kilden bruker
På andre språk...                            


3 svar

stemmer
0

Jeg forventer SET IDENTITY_INSERT er omfangs til kroppen av prosedyren. Den vanligste tilnærmingen jeg har sett er å lage en lagret prosedyre som bruker EXEC å utføre dynamisk SQL inneholder både SET IDENTITY_INSERT og innsatsen selv.

Svarte 29/12/2009 kl. 22:58
kilden bruker

stemmer
5

http://msdn.microsoft.com/en-us/library/ms190356.aspx

Hvis du ser ned, kan du se:

Hvis en SET-setningen kjøres i en lagret prosedyre eller trigger, er verdien av SET-alternativet gjenopprettet etter kontrollen er returnert fra den lagrede prosedyren eller utløseren. Også hvis en SET-setningen er spesifisert i en dynamisk SQL streng som drives ved hjelp av enten sp_executesql eller utføre, er verdien av SET-alternativet gjenopprettet etter kontrollen er returnert fra batch spesifisert i det dynamiske SQL streng.

Svarte 29/12/2009 kl. 23:00
kilden bruker

stemmer
2

Mens omfanget av IDENTITY_INSERT synes å være et problem, løsningen jeg har funnet og testet i EF v4.1 er å åpne tilkoblingen først, slik at økten forblir åpent. Eg

using (SiteDataContext context = SiteDataContext.Create())
{
    context.Connection.Open();
    context.ExecuteStoreCommand("SET IDENTITY_INSERT [EnumValue] ON");

    var val = new EnumValue()
    {
        ID = 2000000,
        Value = "just a test",
    };
    context.AddToEnumValues(val);
    context.SaveChanges();

    context.ExecuteStoreCommand("SET IDENTITY_INSERT [EnumValue] OFF");
}

I testet denne løsningen uten ringer context.Connection.Open (); første, og det klarte ikke som beskrevet. Da jeg lagt linjen det fungerte utmerket.

Svarte 05/07/2013 kl. 21:36
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more