2013-10-30 121 views
1

在我們的SQL數據庫中,我們有一個帶有組合鍵的表格,其中包含我們需要隨時更新的字段。這是我的理解,因爲我們正在使用實體框架,我需要先從數據庫中刪除記錄,然後將該行添加回表中。使用linq更新複合鍵字段

以下是我創建的用於處理「更新」的簡單方法,因爲有許多方法將執行此操作。然而,一旦.SaveChanges()方法是.Remove後叫我拿到DbUpdateConcurrencyException

Store update, insert, or delete statement affected an unexpected number of 
rows (0). Entities may have been modified or deleted since entities were loaded. 
Refresh ObjectStateManager entries. 

不知道我在做什麼錯了,因爲我想刪除的記錄,然後進行更新,然後添加記錄背部。

下面是調用remove/edit方法的方法。當這個方法被調用時,記錄沒有以任何形式或形式改變。

private static void ProcessAllChanges(ZipCodeIndex information, ZipCodeTerritory zipToUpdate) 
    { 
     try 
     { 
      RemoveRecord(zipToUpdate); 

      if (!string.IsNullOrWhiteSpace(information.newTerritory)) zipToUpdate.IndDistrnId = information.newTerritory; 
      if (!string.IsNullOrWhiteSpace(information.newStateCode)) zipToUpdate.StateCode = information.newStateCode; 
      if (!string.IsNullOrWhiteSpace(information.newDescription)) zipToUpdate.DrmTerrDesc = information.newDescription; 
      if (!string.IsNullOrWhiteSpace(information.newChannelCode)) zipToUpdate.ChannelCode = information.newChannelCode; 
      if (zipToUpdate.EndDate == DateTime.MinValue) zipToUpdate.EndDate = DateTime.MaxValue; 

      EditRecord(zipToUpdate); 
      _updated++; 
     } 
     catch (DbEntityValidationException dbEx) 
     { 
      _msg += "Error during update; "; 
      EventLog.WriteEntry("Monet", "Error during ProcessAllChanges: " + zipToUpdate.ToString() + " |EX| " + dbEx.Message); 
     } 
     catch (Exception ex) 
     { 
      _msg += "Error during update; "; 
      EventLog.WriteEntry("Monet", "Error during ProcessAllChanges: " + zipToUpdate.ToString() + " |MESSAGE| " + ex.Message); 
     } 
    } 

而且這裏有兩個helper方法被調用

public static void RemoveRecord(ZipCodeTerritory zipCode) 
    { 
     _db = new AgentResources(); 
     _db.ZipCodeTerritory.Attach(zipCode); 
     _db.ZipCodeTerritory.Remove(zipCode); 
     _db.SaveChanges(); 
    } 

    public static void EditRecord(ZipCodeTerritory zipCode) 
    { 
     _db = new AgentResources(); 
     _db.ZipCodeTerritory.Add(zipCode); 
     _db.SaveChanges(); 
    } 

編輯

基於一對夫婦的評論下面我試圖創建上下文對象的一個​​單獨的實例,但是我使用這種方法收到了同樣的錯誤:

public static void RemoveRecord(ZipCodeTerritory zipCode) 
    { 
     using (AgentResources deleteMe = new AgentResources()) 
     { 
      deleteMe.ZipCodeTerritory.Attach(zipCode); 
      deleteMe.ZipCodeTerritory.Remove(zipCode); 
      deleteMe.SaveChanges();     
     } 
    } 

第二編輯

這是最上面的方法,它調用上面發佈的ProcessAllChanges方法。

public static string TerritoryOnly(ZipCodeIndex updateZip) 
    { 
     if (!string.IsNullOrWhiteSpace(updateZip.newEffectiveDate) || !string.IsNullOrWhiteSpace(updateZip.newEndDate)) 
     { 
      return "Neither effective or end date can be present if updating Territory Code only; "; 
     } 

     RefreshProperties(); 

     foreach (var zipCode in updateZip.displayForPaging.Where(x => x.Update)) 
     { 
      ProcessAllChanges(updateZip, zipCode); 
     } 

     _msg += _updated + " record(s) updated; "; 

     return _msg; 
    } 

第三編輯

每請求這裏是AgentResources完整的類定義,我們DbContext對象

namespace Monet.Models 
{ 
    using System; 
    using System.Data.Entity; 
    using System.Data.Entity.Infrastructure; 

    public partial class AgentResources : DbContext 
    { 
     public AgentResources() 
      : base("name=AgentResources") 
     { 
     } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      throw new UnintentionalCodeFirstException(); 
     } 

     public DbSet<AgentContEd> AgentContEd { get; set; } 
     public DbSet<ContEdCourse> ContEdCourse { get; set; } 
     public DbSet<Course> Course { get; set; } 
     public DbSet<CourseToProduct> CourseToProduct { get; set; } 
     public DbSet<Product> Product { get; set; } 
     public DbSet<ProcessControl> ProcessControl { get; set; } 
     public DbSet<AgentIdToTradingPartner> AgentIdToTradingPartner { get; set; } 
     public DbSet<TradingPartner> TradingPartner { get; set; } 
     public DbSet<Notes> Notes { get; set; } 
     public DbSet<CourseMaterials> CourseMaterials { get; set; } 
     public DbSet<TransactionLog> TransactionLog { get; set; } 
     public DbSet<Agent> Agent { get; set; } 
     public DbSet<AgentIdentification> AgentIdentification { get; set; } 
     public DbSet<BatchDashboard> BatchDashboard { get; set; } 
     public DbSet<BatchPrograms> BatchPrograms { get; set; } 
     public DbSet<FollowUpItems> FollowUpItems { get; set; } 
     public DbSet<sysdiagrams> sysdiagrams { get; set; } 
     public DbSet<AgentProductTraining> AgentProductTraining { get; set; } 
     public DbSet<Channel> Channel { get; set; } 
     public DbSet<RelationshipCodes> RelationshipCodes { get; set; } 
     public DbSet<DropDownValues> DropDownValues { get; set; } 
     public DbSet<QueueUpdates> QueueUpdates { get; set; } 
     public DbSet<MarketingLookup> MarketingLookup { get; set; } 
     public DbSet<TransmissionHistory> TransmissionHistory { get; set; } 
     public DbSet<AgentTransmission> AgentTransmission { get; set; } 
     public DbSet<ZipCodeTerritory> ZipCodeTerritory { get; set; } 
    } 
} 

這裏是ZipCodeTerritory

public partial class ZipCodeTerritory 
{ 
    public string ChannelCode { get; set; } //Composite key field 
    public string DrmTerrDesc { get; set; } 
    public string IndDistrnId { get; set; } 
    public string StateCode { get; set; } //Composite key field 
    public string ZipCode { get; set; } //Composite key field 
    public System.DateTime? DisplayEndDate { get; set; } 
    public System.DateTime EndDate { get; set; } //Composite key field 
    public System.DateTime EffectiveDate { get; set; } 
    public string LastUpdateId { get; set; } 
    public Nullable<System.DateTime> LastUpdateDate { get; set; } 
} 
+0

它看起來像你離開你的背景下開'_db'但隨後在你的輔助方法,每次調用構造函數'_db =新AgentResources();'你爲什麼這樣做?很難說,因爲你已經留下了大部分代碼。你在同一班上表現出的一切嗎?爲什麼是靜態方法? – EkoostikMartin

+0

這些方法是靜態的,因爲它們是公共助手類的一部分。網頁上可能會出現許多更新,因此我們決定使用單獨的.cs文件清理代碼。這些方法只是將模型對象傳遞給它('ZipCodeTerritory'模型)。 – NealR

+0

這也是爲什麼上下文在每次使用時都調用構造函數的原因。我們希望確保每次都使用乾淨的平板,而不是以前的交易。 – NealR

回答

1

試試這個:

public static void RemoveRecord(ZipCodeTerritory zipCode) 
{ 
    using(var _newdb = new AgentResources()) 
    { 
     ZipCodeTerritory zipCodeRemove = new ZipCodeTerritory(); 
     zipCodeRemove.channelCode = zipCode.channelCode; 
     zipCodeRemove.stateCode = zipCode.stateCode; 
     zipCodeRemove.zipCode= zipCode.zipCode; 
     zipCodeRemove.endDate = zipCode.endDate; 

     _newdb.ZipCodeTerritory.Attach(zipCodeRemove); 
     _newdb.ZipCodeTerritory.Remove(zipCodeRemove); 
     //((IObjectContextAdapter)_newdb).ObjectContext.Refresh(
                // RefreshMode.ClientWins 
                //, zipCode); 
     _newdb.SaveChanges(); 
    } 
} 
+0

Visual Studio無法識別'.Refresh'方法或'RefreshMode'枚舉(我認爲?)。是否有我需要的名稱空間? – NealR

+0

System.Data.Entity程序集 - http://msdn.microsoft.com/en-us/library/bb896255.aspx – EkoostikMartin

+0

奇怪的是,如果我添加'System.Data.Objects'我得到了'RefreshMode'但是什麼也沒有如果我添加'System.Data.Entity'。 $#&%^ * @微軟...... – NealR