Ho un’entity framework Account che ha tutti i campi in “UpdateCheck = Never” tranne un campo. Il campo “ModifiedTime” utilizza “UpdateCheck = Always”. L’intenzione è: il controllo della concorrenza deve essere basato solo sulla colonna “ModifiedTime”.
Per scopo di test sto fornendo il valore “ModifiedTime” codificato nel codice C #. Quindi non è necessario recuperare alcun valore dal database per la concorrenza. Ancora il codice aggiornerà il database solo se invoco il metodo Refresh. Questo sembra strano. Qualche approccio per evitare questo?
Fare riferimento alla sezione “Aggiornamento senza ricerca” in http://msdn.microsoft.com/en-us/library/bb386929.aspx
Nota: sto cercando di evitare l’istruzione SELECT non usando Refresh
SQL generato
SELECT [t0].[AccountNumber], [t0].[AccountType], [t0].[Duration], [t0].[DepositedAmount], [t0].[Prefernce], [t0].[Comment], [t0].[ModifiedTime] FROM [dbo].[Account] AS [t0] WHERE [t0].[AccountNumber] = @p0 -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1
Query di aggiornamento
UPDATE [dbo].[Account] SET [AccountType] = @p2, [Duration] = @p3 WHERE ([AccountNumber] = @p0) AND ([ModifiedTime] = @p1) -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- @p1: Input DateTime (Size = -1; Prec = 0; Scale = 0) [6/25/2012 5:08:32 PM] -- @p2: Input NChar (Size = 10; Prec = 0; Scale = 0) [SUCESS] -- @p3: Input Int (Size = -1; Prec = 0; Scale = 0) [2] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1
Struttura della tabella
CREATE TABLE [dbo].[Account]( [AccountNumber] [int] NOT NULL, [AccountType] [nchar](10) NOT NULL, [Duration] [int] NOT NULL, [DepositedAmount] [int] NULL, [Prefernce] [int] NULL, [Comment] [nvarchar](50) NULL, [ModifiedTime] [datetime] NOT NULL, CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED ( [AccountNumber] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
Codice C #
public virtual void UpdateChangesByAttach(T entity) { if (Context.GetTable().GetOriginalEntityState(entity) == null) { //If it is not already attached Context.GetTable().Attach(entity); Context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, entity); } } public void UpdateAccount() { //Used value from previous select DateTime previousDateTime = new DateTime(2012, 6, 25, 17, 8, 32, 677); RepositoryLayer.Account accEntity = new RepositoryLayer.Account(); accEntity.AccountNumber = 1; accEntity.AccountType = "SUCESS"; accEntity.ModifiedTime = previousDateTime; accEntity.Duration = 2; accountRepository.UpdateChangesByAttach(accEntity); accountRepository.SubmitChanges(); }
Tabella dati
LETTURA:
LINQ to SQL: come aggiornare l’unico campo senza recuperare l’intera quadro
Aggiorna senza prima selezionare i dati in LINQ 2 SQL?
AGGIORNA SELEZIONA in LINQ a SQL
linq to sql aggiorna le righe multiple
Valori predefiniti (di variabili C #) Problema in LINQ a SQL Update
Grazie a @sgmoore. I valori da aggiornare vengono impostati dopo il metodo Attach. Ora sta funzionando. C’è ancora qualcosa da migliorare?
SQL generato
UPDATE [dbo].[Account] SET [AccountType] = @p2, [Duration] = @p3, [ModifiedTime] = @p4 WHERE ([AccountNumber] = @p0) AND ([ModifiedTime] = @p1) -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- @p1: Input DateTime (Size = -1; Prec = 0; Scale = 0) [6/25/2012 5:08:32 PM] -- @p2: Input NChar (Size = 10; Prec = 0; Scale = 0) [NEXT] -- @p3: Input Int (Size = -1; Prec = 0; Scale = 0) [4] -- @p4: Input DateTime (Size = -1; Prec = 0; Scale = 0) [6/26/2012 10:29:19 AM] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1
CODICE
public void UpdateAccount() { //Used value from previous select DateTime previousDateTime = new DateTime(2012, 6, 25, 17, 8, 32, 677); RepositoryLayer.Account accEntity = new RepositoryLayer.Account(); accEntity.AccountNumber = 1; //Primary Key accEntity.ModifiedTime = previousDateTime; //Concurrency column accountRepository.UpdateChangesByAttach(accEntity); //Values to be modified after Attach accEntity.AccountType = "NEXT"; accEntity.ModifiedTime = DateTime.Now; accEntity.Duration = 4; accountRepository.SubmitChanges(); } public virtual void UpdateChangesByAttach(T entity) { if (Context.GetTable().GetOriginalEntityState(entity) == null) { //If it is not already attached Context.GetTable ().Attach(entity); } }