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


 

 

posted @   你听海是不是在笑  阅读(4685)  评论(26编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示