假设我有一个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多个字段,因此我正在寻找更好的方法。
对于这种情况,我会给出任何好的解决方案。
答案 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;
}
}