LINQ to SQL:当“UpdateCheck = Never"时更新而不刷新 [英] LINQ to SQL: Updating without Refresh when “UpdateCheck = Never”

查看:29
本文介绍了LINQ to SQL:当“UpdateCheck = Never"时更新而不刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Account 实体,它包含UpdateCheck = Never"中的所有字段,只有一个字段除外.ModifiedTime"字段使用UpdateCheck=Always".目的是 – 并发检查应仅基于ModifiedTime"列.

出于测试目的,我提供了在 C# 代码中硬编码的ModifiedTime"值.因此不需要从数据库中获取任何值以进行并发.只有当我调用 Refresh 方法时,代码才会更新数据库.这看起来很奇怪.有什么方法可以避免这种情况吗?

请参阅:

  • 无需先在 LINQ 2 中选择数据即可更新SQL?

  • LINQ to SQL 中的 UPDATE SELECT

  • linq to sql 更新多行

  • 默认值(C# 变量)LINQ to SQL 更新中的问题

  • <小时>

    解决方案

    感谢 @sgmoore .要更新的值在 Attach 方法之后设置.现在它正在工作.还有什么需要改进的吗?

    生成的 SQL

    更新 [dbo].[账户]SET [AccountType] = @p2, [Duration] = @p3, [ModifiedTime] = @p4WHERE ([AccountNumber] = @p0)AND ([ModifiedTime] = @p1)-- @p0: 输入整数 (大小 = -1; Prec = 0; 比例 = 0) [1]-- @p1:输入日期时间(大小 = -1;Prec = 0;比例 = 0)[6/25/2012 5:08:32 PM]-- @p2: 输入 NChar (Size = 10; Prec = 0; Scale = 0) [NEXT]-- @p3:输入整数(大小 = -1;Prec = 0;比例 = 0)[4]-- @p4:输入日期时间(大小 = -1;Prec = 0;比例 = 0)[6/26/2012 10:29:19 AM]-- 上下文:SqlProvider(Sql2008) 模型:AttributedMetaModel Build:4.0.30319.1

    代码

     public void UpdateAccount(){//使用前一个选择的值DateTime previousDateTime = new DateTime(2012, 6, 25, 17, 8, 32, 677);RepositoryLayer.Account accEntity = new RepositoryLayer.Account();accEntity.AccountNumber = 1;//首要的关键accEntity.ModifiedTime = previousDateTime;//并发列accountRepository.UpdateChangesByAttach(accEntity);//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){//如果还没有附加Context.GetTable().Attach(entity);}}

    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

    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


    解决方案

    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);
            }
    
        }
    

    这篇关于LINQ to SQL:当“UpdateCheck = Never"时更新而不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆