ASP.NET WebForms在运行时将插入操作更改为更新

时间:2017-04-21 07:00:57

标签: c# asp.net webforms formview entitydatasource

假设我有一个FormView的页面,其中有一个表单允许将文章注册到数据库中。用户可以填写一些属性,如数字,描述等。我使用EntityDataSource

我可以执行插入/更新操作。问题是在某些情况下(确切地说,如果具有相同IsDeleted的对象的Number属性设置为true),我想取消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事件处理程序NewValues对象的FormViewUpdateEventArgs属性有一些默认值 - 而不是用户输入的值。

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

是否有可能以这种方式工作?

我可以在Entity中手动创建ItemInserting对象并手动分配所有值,但对象有200多个字段,因此我正在寻找更好的方法。

对于这种情况,我会给出任何好的解决方案。

1 个答案:

答案 0 :(得分: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;
   }
}