问题:因为每次更新的时候只是某个类的一部分,但是这个类的属性比较多.
更新函数如下
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);
}