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(
1 set );
        }
复制代码


 

 


本文转自 你听海是不是在笑 博客园博客,原文链接:http://www.cnblogs.com/nuaalfm/archive/2008/08/11/1265268.html  ,如需转载请自行联系原作者


相关文章
|
JavaScript 索引
面试题分享,修改数据无法更新UI
面试题分享,修改数据无法更新UI
132 0
面试题分享,修改数据无法更新UI
|
Web App开发 数据库 容器
EntityFramework中常用的数据删除方式速度对比
EntityFramework中常用的数据删除方式速度对比http://www.bieryun.com/3375.html 最近在学EF,目前了解到删除操作有三种方式, 第一,官方推荐的先查询数据,再根据查询的对象,删除对象。
1412 0