当前位置:主页   - 电脑 - 网站开发 - ASP.Net
linq更新部分数据时遇到的问题及解决办法
来源:网络   作者:   更新时间:2012-08-04
收藏此页】    【字号    】    【打印】    【关闭

  问题:因为每次更新的时候只是某个类的一部分,但是这个类的属性比较多.

  更新函数如下

static void updateRe(log n)
    {
      using (DataClasses1DataContext dc = new DataClasses1DataContext())
      {
        using (StreamWriter sw=new StreamWriter("t.log"))
        {
          dc.Log = sw;
          dc.log.Attach(n);
          dc.Refresh_PB_PB_PB_PB_PB_PB_PB(Refresh_PB_PB_PB_PB_PB_PB_PBMode.KeepCurrentValues,n);
  
          dc.SubmitChanges();
        }
      }
    }
  
staticvoidMain(string[]args)
    {
      logn1=newlog();
      n1.logId=1;
      n1.logMessage="xxxx";
  
      updateRe(n1);
    }

  这时候产生的sql如下

SELECT [t0].[logId], [t0].[logMessage], [t0].[x]
FROM [dbo].[log] AS [t0]
WHERE [t0].[logId] = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
  
UPDATE [dbo].[log]
SET [logMessage] = @p1, [x] = @p2
WHERE [logId] = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- @p1: Input VarChar (Size = 4; Prec = 0; Scale = 0) [xxxx]
-- @p2: Input NChar (Size = 10; Prec = 0; Scale = 0) [Null]

  问题就是这样做会将你没有符过值的都更新为Null,我继续做实验,将main函数改为如下

staticvoidMain(string[]args)
    {
      DataClasses1DataContextdc=newDataClasses1DataContext();
      logn1=(fromxindc.log
           selectx).SingleOrDefault(c=>c.logId==1);
      n1.logMessage="xxxy";
  
      updateRe(n1);
    }

  会引发"已尝试 Attach 或 Add 实体,该实体不是新实体,可能是从其他 DataContext 中加载来的。不支持这种操作。"异常,没找到把n1从它的DataContext脱离的办法.所以我使用如下的解决方案:

  在log的部分类中书写克隆方法:

publicpartialclasslog
  {
    publiclogClone()
    {
      logl=newlog();
      l.logId=this.logId;
      l.logMessage=this.logMessage;
      l.x=this.x;
      returnl;
    }
 }
staticvoidMain(string[]args)
    {
      DataClasses1DataContextdc=newDataClasses1DataContext();
      logn1=((fromxindc.log
           selectx).SingleOrDefault(c=>c.logId==1)).Clone();
      n1.logMessage="xxxy";
      updateRe(n1);
}

  生成的sql语句如下

SELECT [t0].[logId], [t0].[logMessage], [t0].[x]
FROM [dbo].[log] AS [t0]
WHERE [t0].[logId] = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
  
UPDATE [dbo].[log]
SET [logMessage] = @p1
WHERE [logId] = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- @p1: Input VarChar (Size = 4; Prec = 0; Scale = 0) [xxxy]

  感觉这个Clone()方法也不是好的解决方案,大家有什么好的想法么?

  网友:@Gray Zhang 的这个方法我觉得不错,<理如下:

staticvoidUpdate(intid,Action<log>updater)
    {
      using(DataClasses1DataContextctx=newDataClasses1DataContext())
      {
        ctx.Log=Console.Out;
        logentity=ctx.log.First(c=>c.logId==id);
        //执行updater
        updater(entity);
        ctx.SubmitChanges();
      }
    }
    publicstaticvoidset(logl)
    {
      l.logMessage="xxtx";
    }
    staticvoidMain(string[]args)
    {
     eUpdate(1,set);
    }

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明