問題:因為每次更新的時候只是某個類的一部分,但是這個類的屬性比較多.
更新函數如下
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); }