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);
}
{
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 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中的相应属性

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 的这个方法我觉得不错,整理如下:
{
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);
}
作者:Lance
出处:http://www.cnblogs.com/nuaalfm/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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的设计模式综述