Default Values (of C# variables) Issue in LINQ to SQL Update
我有以下代码用于用linq to sql更新account表。AccountNumber是主键列。唯一需要更新的值是accounttype;但是持续时间也会更新为零(int的默认值)。我们如何避免这种不必要的覆盖?
注意:我使用的是附加方法
注意:我理解这种行为的原因。"DataContext无法区分赋值为零的字段和仅未赋值的字段。"。我正在寻找解决办法来克服这个问题。
1 2 | [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Duration", DbType="Int NOT NULL" public int Duration |
表数据
表结构:
1 2 3 4 5 6 7 8 9 10 | CREATE TABLE [dbo].[Account]( [AccountNumber] [int] NOT NULL, [AccountType] [nchar](10) NOT NULL, [Duration] [int] NOT NULL, [DepositedAmount] [int] 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] |
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public void UpdateAccount() { RepositoryLayer.Account acc1 = new RepositoryLayer.Account(); acc1.AccountNumber = 4; acc1.AccountType ="Verify"; accountRepository.UpdateChangesByAttachAndRefresh(acc1); accountRepository.SubmitChanges(); } public virtual void UpdateChangesByAttachAndRefresh(T entity) { //Can GetOriginalEntityState cause any bug? Is it unnecessary? if (GetTable().GetOriginalEntityState(entity) == null) { //If it is not already attached Context.GetTable<T>().Attach(entity); Context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, entity); } } |
生成的SQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | UPDATE [dbo].[Account] SET [AccountType] = @p3, [Duration] = @p4 WHERE ([AccountNumber] = @p0) AND ([AccountType] = @p1) AND ([Duration] = @p2) AND ([DepositedAmount] IS NULL) -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [4] -- @p1: Input NChar (Size = 10; Prec = 0; Scale = 0) [TEST ] -- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [10] -- @p3: Input NChar (Size = 10; Prec = 0; Scale = 0) [Verify] -- @p4: Input Int (Size = -1; Prec = 0; Scale = 0) [0] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 |
阅读:
LINQ to SQL能否在插入时省略未指定的列,以便使用数据库默认值?
如何将枚举绑定到bit或int的dbtype?
Linq to SQL:为什么我会收到标识插入错误?
linq to sql:updatecheck=never时不刷新更新
应该这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int number = 4; var acc1 = new accountRepository.Accounts.Where(a => a.Number == number).FirstOrDefault(); if (acc1 == null) { // Not found by ID, create new acc1 = new RepositoryLayer.Account(); acc1.Number = number; accountRepository.Accounts.AddObject(acc1); } acc1.AccountType ="Verify"; accountRepository.SubmitChanges(); |
我通过更改更新方法来解决这个问题,方法是按照linq to sql中的答案:当"updatecheck=never"时不刷新更新
对于Duration列,UpdateCheck设置为Never
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public void UpdateAccount() { //Used value from previous select DateTime previousDateTime = new DateTime(2012, 6, 26, 11, 14, 15, 327); int prevDuration = 0; RepositoryLayer.Account accEntity = new RepositoryLayer.Account(); accEntity.AccountNumber = 1; //Primary Key accEntity.ModifiedTime = previousDateTime; //Concurrency column //accEntity.Duration = prevDuration; accountRepository.UpdateChangesByAttach(accEntity); //Values to be modified after Attach accEntity.AccountType ="WIN-WIN"; accEntity.ModifiedTime = DateTime.Now; try { accountRepository.SubmitChanges(); } catch(System.Data.Linq.ChangeConflictException e) { throw new Exception(e.Message); } } public virtual void UpdateChangesByAttach(T entity) { if (Context.GetTable<T>().GetOriginalEntityState(entity) == null) { //If it is not already attached Context.GetTable<T>().Attach(entity); } } |
生成的SQL
1 2 3 4 5 6 7 8 9 | UPDATE [dbo].[Account] SET [AccountType] = @p2, [ModifiedTime] = @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/26/2012 11:14:15 AM] -- @p2: Input NChar (Size = 10; Prec = 0; Scale = 0) [WIN-WIN] -- @p3: Input DateTime (Size = -1; Prec = 0; Scale = 0) [6/26/2012 11:16:29 AM] |