Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

c# - LINQ to SQL: Updating without Refresh when “UpdateCheck = Never”

I have an Account entity which has all fields in “UpdateCheck = Never” except one field. The “ModifiedTime” field uses “UpdateCheck=Always”. The intention is – concurrency check should be based on “ModifiedTime” column only.

For the test purpose I am supplying the “ModifiedTime” value hard coded in C# code. So there is no need to fetch any value from database for concurrency. Still the code will update the database only if I call for the Refresh method. This seems strange. Any approach to avoid this?

Refer: "Updating Without Querying" section in http://msdn.microsoft.com/en-us/library/bb386929.aspx

Note: I am trying to avoid the SELECT statement by not using Refresh

Generated SQL

 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

Update Query

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

Table Structure

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]

C# Code

    public virtual void UpdateChangesByAttach(T entity)
    {

        if (Context.GetTable<T>().GetOriginalEntityState(entity) == null)
        {
            //If it is not already attached
            Context.GetTable<T>().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();

    }

Table Data

enter image description here

READING:

  1. LINQ to SQL: how to update the only field without retrieving whole entity

  2. Update without first selecting data in LINQ 2 SQL?

  3. UPDATE SELECT in LINQ to SQL

  4. linq to sql update mulitple rows

  5. Default Values (of C# variables) Issue in LINQ to SQL Update


See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to @sgmoore . The values to be updated are set after the Attach method. Now it is working. Is there anything yet to improve?

Generated SQL

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

CODE

    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<T>().GetOriginalEntityState(entity) == null)
        {
            //If it is not already attached
            Context.GetTable<T>().Attach(entity);
        }

    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...