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

                updateRe(n1);
            }

    static void Main(string[] args)
            {
                log n1 
    = new log() ;
                n1.logId 
    = 1;
                n1.logMessage 
    = "xxxx";

    这时候产生的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函数改为如下

    static void Main(string[] args)
            {
                DataClasses1DataContext dc 
    = new DataClasses1DataContext();
                log n1 
    = (from x in dc.log
                          select x).SingleOrDefault(c 
    => c.logId == 1);
                n1.logMessage 
    = "xxxy";

                updateRe(n1);
            }

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

    public partial class log
        {
            
    public log Clone()
            {
                log l 
    = new log();
                l.logId 
    = this.logId;
                l.logMessage 
    = this.logMessage;
                l.x 
    = this.x;
                
    return l;
            }
       }
    static void Main(string[] args)
            {
                DataClasses1DataContext dc 
    = new DataClasses1DataContext();
                log n1 
    = ((from x in dc.log
                          select x).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()方法也不是好的解决方案,大家有什么好的想法么?

     ps:

    可以使用反射代码自动拷贝dbml中的相应属性

    Code
    class Utility
        {
            
    public static T Clone<T>(T source) where T: new() 
            {
                T t 
    = new T();
                var ps 
    = source.GetType().GetProperties().Where(p => p.GetCustomAttributes(false)
                   .Where(a 
    => a is System.Data.Linq.Mapping.ColumnAttribute).Count() != 0);
                
    foreach (var item in ps)
                {
                    t.GetType().GetProperty(item.Name).SetValue(t, item.GetValue(source, 
    null), null);
                }
                
    return t;
            }
        }

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

    static void Update(int id, Action<log> updater)
            {
                
    using (DataClasses1DataContext ctx = new DataClasses1DataContext())
                {
                    
    ctx.Log = Console.Out;
                    log entity 
    = ctx.log.First(c => c.logId == id);
                    
    //执行updater
                    updater(entity);
                    ctx.SubmitChanges();
                }
            }
            
    public static void set(log l)
            {
                l.logMessage 
    = "xxtx";
            }
            
    static void Main(string[] args)
            {
                Update(
    1set);
            }


     

  • 相关阅读:
    windows下搭建hadoopproject(一)
    inspect模块---检查活动对象
    Python的datetime模块分析
    深入理解python之self
    request payload
    计算机基础知识
    pycharm常用快捷键
    英语学习五大法则
    基础语法
    英语基本语法
  • 原文地址:https://www.cnblogs.com/nuaalfm/p/1265268.html
Copyright © 2011-2022 走看看