天天看點

linq更新部分資料時遇到的問題及解決辦法

問題:因為每次更新的時候隻是某個類的一部分,但是這個類的屬性比較多.

更新函數如下

<a></a>

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

-- @p1: Input VarChar (Size = 4; Prec = 0; Scale = 0) [xxxx]

-- @p2: Input NChar (Size = 10; Prec = 0; Scale = 0) [Null]

問題就是這樣做會将你沒有符過值的都更新為Null,我繼續做實驗,将main函數改為如下

            DataClasses1DataContext dc = new DataClasses1DataContext();

            log n1 = (from x in dc.log

                      select x).SingleOrDefault(c =&gt; c.logId == 1);

            n1.logMessage = "xxxy";

會引發"已嘗試 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;

   }

            log n1 = ((from x in dc.log

                      select x).SingleOrDefault(c =&gt; c.logId == 1)).Clone();

}

生成的sql語句如下

SET [logMessage] = @p1

-- @p1: Input VarChar (Size = 4; Prec = 0; Scale = 0) [xxxy]

感覺這個Clone()方法也不是好的解決方案,大家有什麼好的想法麼?

 ps:

可以使用反射代碼自動拷貝dbml中的相應屬性

linq更新部分資料時遇到的問題及解決辦法

Code

class Utility

        public static T Clone&lt;T&gt;(T source) where T: new() 

            T t = new T();

            var ps = source.GetType().GetProperties().Where(p =&gt; p.GetCustomAttributes(false)

               .Where(a =&gt; 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&lt;log&gt; updater)

            using (DataClasses1DataContext ctx = new DataClasses1DataContext())

                ctx.Log = Console.Out;

                log entity = ctx.log.First(c =&gt; 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  ,如需轉載請自行聯系原作者