【问题标题】:LINQ to SQL: Updating without Refresh when “UpdateCheck = Never”LINQ to SQL:当“UpdateCheck = Never”时更新而不刷新
【发布时间】:2012-06-26 17:30:17
【问题描述】:

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

出于测试目的,我提供了用 C# 代码硬编码的“ModifiedTime”值。所以不需要从数据库中获取任何值来实现并发。只有当我调用 Refresh 方法时,代码才会更新数据库。这似乎很奇怪。有什么方法可以避免这种情况?

请参阅:http://msdn.microsoft.com/en-us/library/bb386929.aspx 中的“无需查询即可更新”部分

注意:我试图通过不使用 Refresh 来避免 SELECT 语句

生成的 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 [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

表结构

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#代码

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

    }

表格数据

阅读:

  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


【问题讨论】:

  • 如果您希望更新它们,您是否需要在设置 AccountType 和 Duration 之前附加实体?
  • @sgmoore。谢谢。有效。请看下面的答案。有什么需要改进的地方吗?

标签: c# .net linq linq-to-sql


【解决方案1】:

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

生成的 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

代码

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

    }

【讨论】:

  • 我只想向任何借用此代码的人添加警告。例如,如果您想将列重置为默认值,例如 accEntity.AccountType 为 null,那么在附加后,您应该首先将 accEntity.AccountType 设置为某个非 null 值,然后将其设置为 null,以便该属性为标记为已更改。
猜你喜欢
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
相关资源
最近更新 更多