none
使用LINQtoEF儲存資料的問題 RRS feed

  • 問題

  • 各位前輩好

    我接觸mvc c#以及linq to ef有段時間了
    但有件事一直搞不懂,或找不到新的寫法

    也就是當我要更新一筆資料時,
    我會寫出以下的程式來run

    public void UpdateData(Data UpdateData)
    { 
       //Step1.抓出原有資料
       Data exdb = (from c in _db.datatable
                 where c.data_id == UpdateData.data_id
                 select c).FirstOrDefault();
       //Step2.將資料寫入UpdateData
       UpdateData.title = exdb.title;
       UpdateData.date = exdb.date;
       UpdateData.writer = exdb.writer;
    
       //Step3.存入資料庫
       _db.ApplyCurrentValues(exdb.EntityKey.EntitySetName, UpdateData);
       _db.SaveChanges();
    }
    

     

    程式流程是,我在想要修改Data資料集中
    某一筆資料的content欄位資料
    其它欄位都不會動到

    但我發現,如果不撈出原有資料,並放到UpdateData中
    在儲存更新資料後
    原有其它欄位資料,都會被空白覆蓋

    也因此,我必須要寫上述程式碼中step1與2的部份
    也就是除了content外,我還要將其它欄位撈出並寫進UpdateData中
    之後再進行step3,才有辦法防止這一筆其它欄位被空白覆蓋的情況發生

    但這樣一來,我遇到一些資料表,欄位很多的情況下
    程式碼也會跟著變多(一欄等於一行程式碼)

    因此想請教,還有別的寫法嗎?

    2010年8月27日 上午 06:57

解答

  • 如果是EF1,請試這個寫法

    public void UpdateData(Data UpdateData)
    { 
      var key = _db.CreateEntityKey("UpdateDataSet", UpdateData);
      object originEntity;
    
      //存入資料庫
      if (_db.TryGetObjectByKey(key, out originEntity)
      {
        _db.ApplyCurrentValues(key.EntitySetName, UpdateData);
        _db.SaveChanges();
      }
    }
    
    

    如果是EF4,請改用這個寫法

    public void UpdateData(Data UpdateData)
    { 
    
      _db.Attach(UpdateData);
      _db.ObjectStateManager.ChangeObjectState(UpdateData, EntityState.Modified);
    
      //存入資料庫
      _db.SaveChanges();
    
    }
    
    

     

    2010年9月8日 上午 08:37
  • 提供另一種寫法供您參考。

    using (testEntities context = new testEntities())
          {
            ObjectQuery<User> user = context.Users;
            //依據PK取出資料
            IQueryable<User> query = from p in user
                         where p.UserName == "User1"
                         select p;
            //判斷是否有資料
            if (query.Any())
            {
              //更新欄位
              query.First().Password = "1111";
              try
              {
                //將資料儲存
                context.SaveChanges();
              }
              catch
              {
              }
            }
          }
    


    http://www.dotblogs.com.tw/terrychuang/
    2011年1月26日 上午 07:50

所有回覆

  • 小七您好:

        依我的經驗,並不會像您說的那樣,會覆蓋掉沒有指定更新值的其他欄位!

        但我和你的寫法有兩個不同:

    1.我用的是VB

    2.我是直接修改Object Context中的資料

    3.在Step3中我並未執行下列敘述:

    _db.ApplyCurrentValues(exdb.EntityKey.EntitySetName, UpdateData);

    以下附上我的VB程式片斷:

                    ' 取得Object Context中目前這一筆記錄的產品資料表物件
                    Dim pro = (From product In enti.產品基本資料表 _
                              Where product.產品編號 = TextBox6.Text _
                              Select product).First
                    ' 異動Object Context中目前這一筆記錄的內容
                    pro.產品名稱 = TextBox7.Text : pro.定價 = TextBox8.Text
                    pro.庫存量 = TextBox9.Text : pro.安全庫存 = TextBox10.Text
                    pro.產品外觀 = P1FileName : pro.照片 = b
                    ' 異動資料庫中的資料
                    enti.SaveChanges()

     

     

    2010年9月2日 上午 03:56
  • 抱歉,看錯問題,再做修改

    2010年9月7日 上午 03:36
  • 如果是EF1,請試這個寫法

    public void UpdateData(Data UpdateData)
    { 
      var key = _db.CreateEntityKey("UpdateDataSet", UpdateData);
      object originEntity;
    
      //存入資料庫
      if (_db.TryGetObjectByKey(key, out originEntity)
      {
        _db.ApplyCurrentValues(key.EntitySetName, UpdateData);
        _db.SaveChanges();
      }
    }
    
    

    如果是EF4,請改用這個寫法

    public void UpdateData(Data UpdateData)
    { 
    
      _db.Attach(UpdateData);
      _db.ObjectStateManager.ChangeObjectState(UpdateData, EntityState.Modified);
    
      //存入資料庫
      _db.SaveChanges();
    
    }
    
    

     

    2010年9月8日 上午 08:37
  • 提供另一種寫法供您參考。

    using (testEntities context = new testEntities())
          {
            ObjectQuery<User> user = context.Users;
            //依據PK取出資料
            IQueryable<User> query = from p in user
                         where p.UserName == "User1"
                         select p;
            //判斷是否有資料
            if (query.Any())
            {
              //更新欄位
              query.First().Password = "1111";
              try
              {
                //將資料儲存
                context.SaveChanges();
              }
              catch
              {
              }
            }
          }
    


    http://www.dotblogs.com.tw/terrychuang/
    2011年1月26日 上午 07:50
  • I am doing in this way as well,

     

    using (UserEntities context = new UserEntities())
       {
        string userName = Common.Common.GetUserName(HttpContext.Current);
        if (!string.IsNullOrEmpty(userName))
        {
         var user = (from d in context.tblUsers
            where d.User_LoginName == userName
            select d);
    
         if (user.Count() == 0)
         {
          tblUser newUser = tblUser.CreatetblUser(0, userName,
            Common.Common.GetUserCommonName(HttpContext.Current),
            Common.Common.GetUserEmail(HttpContext.Current), false,
            false, 1, 1, DateTime.UtcNow, DateTime.UtcNow);
          newUser.User_LastAccessDate = DateTime.UtcNow;
          context.AddTotblUsers(newUser);
          context.SaveChanges();
         }
         else
         {
          user.SingleOrDefault().User_LastAccessDate = DateTime.UtcNow;
          context.SaveChanges();
         }
        }
       }
    

    大家一齊探討、學習和研究,謝謝!
    Microsoft MVP, Microsoft Community Star(TW & HK), MCT,
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD
    2011年1月26日 上午 10:24