2017-04-21 66 views
0

比方說,我有一個頁面FormView,其中有一個表單允許將文章註冊到數據庫中。用戶可以填寫一些屬性,如號碼,說明等我使用EntityDataSourceASP.NET WebForms在運行時將插入操作更改爲更新

我可以執行插入/更新操作。問題是,在某些情況下(確切地說,如果具有相同Number的對象的屬性IsDeleted設置爲true),我希望cancell Insert操作並執行Update。要做到這一點,我開始有這樣的事情:

protected void ArticleFormView_ItemInserting(object sender, FormViewInsertEventArgs e) 
{ 
    string articleNo = e.Values[ "Number" ].ToString(); 

    // ...some other things... 

    if (this.ShouldUpdateInsteadOfInsert(articleNo)) 
    { 
     e.Cancel = true; //cancel insert 
     this.ArticleFormView.ChangeMode(FormViewMode.Edit); 
     this.ArticleFormView.UpdateItem(false); 
     return; 
    } 
} 

這成功地取消Insert並調用Update。但是在ArticleFormView_ItemUpdating事件處理程序屬性NewValuesFormViewUpdateEventArgs對象中有一些默認值 - 不是用戶輸入的值。

protected void ArticleFormView_ItemUpdating(object sender, FormViewUpdateEventArgs e) 
{ 
    // e.NewValues["Number"] - not the same as 
    // e.Values["Number"] from ArticleFormView_ItemInserting 
} 

有沒有可能使它以這種方式工作?

我可以在ItemInserting中手動創建一個Entity對象並手動分配所有值,但對象有200多個字段,所以我正在尋找更好的方法。

我會爲這種情況提供一個很好的解決方案。

回答

0

不過,如果有人知道更好的解決方案,請回復。

我設法寫一個代碼映射使用反射值。我不調用Update方法,但我在ItemInserting中手動執行數據庫更新。

protected void ArticleFormView_ItemInserting(object sender, FormViewInsertEventArgs e) 
{ 
    string articleNo = e.Values[ "Number" ].ToString(); 

    // ...some other things... 

    if (this.ShouldUpdateInsteadOfInsert(articleNo)) // (property IsDeleted = true) 
    { 
     // cancel insert 
     e.Cancel = true; 

     using (StoreEntities ctx = new StoreEntities()) 
     { 
      // get "deleted" article 
      var restoredArticle = ctx.Articles.First(i => i.Number == articleNo); 

      // "restore" it 
      restoredArticle.IsDeleted = false; 

      var type = restoredArticle.GetType(); 
      foreach (var propertyInfo in type.GetProperties()) 
      { 
       if (propertyInfo.CanWrite) 
       { 
        // ignore some values that should not be changed 
        if (propertyInfo.Name == "Number" || propertyInfo.Name == "IsDeleted" || propertyInfo.Name == "ID" || propertyInfo.Name == "EntityKey") 
         continue; 

        // update other properties, handle non convertible types separately 
        if (propertyInfo.PropertyType == typeof(int)) 
         propertyInfo.SetValue(restoredArticle, e.Values[ propertyInfo.Name ] == null ? (int?)null : Convert.ToInt32(e.Values[ propertyInfo.Name ]), null); 
        else if (propertyInfo.PropertyType == typeof(decimal)) 
         propertyInfo.SetValue(restoredArticle, e.Values[ propertyInfo.Name ] == null ? (decimal?)null : Convert.ToDecimal(e.Values[ propertyInfo.Name ]), null); 
        else 
         propertyInfo.SetValue(restoredArticle, e.Values[ propertyInfo.Name ], null); 
       } 
      } 
      ctx.SaveChanges(); 
     } 

     return; 
    } 
}