zoukankan      html  css  js  c++  java
  • linq更新部分数据时遇到的问题及解决办法

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

      更新函数如下

    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(RefreshMode.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)
        {
          Update(1,set);
        }

  • 相关阅读:
    linux下利用valgrind工具进行内存泄露检测和性能分析
    Linux下内存泄漏工具
    linux下将不同线程绑定到不同core和cpu上——pthread_setaffinity_np
    Linux下getopt()函数
    SparkStreaming+Kafka整合
    Hive+Sqoop+Mysql整合
    crontab
    Hive与Hbase整合
    关系数据库数据与hadoop数据进行转换的工具
    Flume+Kafka+Storm+Hbase+HDSF+Poi整合
  • 原文地址:https://www.cnblogs.com/weihengblogs/p/2880522.html
Copyright © 2011-2022 走看看