我有一个使用ASP.NET动态数据和实体框架4.1(代码优先)生成的产品管理网站。
我开始创建一种批量编辑行的方法。我有我想要批量编辑的列的编辑控件(我创建了一个名为EditableInBulk的新属性,我用它来装饰我的属性)。我还在GridView中添加了一个新列,其中有一个复选框,指示是否应对该行进行批量编辑。
现在剩下的就是我需要以编程方式更新我使用“编辑”检查过的行。
这是我用来查找已检查行的代码,缺少的是实际更新数据并保持不变。
// Find all items that will be edited
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType != DataControlRowType.DataRow)
continue;
// Fetch the item index of the rows that has "Edit" checked
var editMe = row.Cells[1].Controls.OfType<CheckBox>().Any(ch => ch.Checked);
if (editMe)
{
// Edit the fields in the row and persist
}
}
我应该可以在GridView控件中使用UpdateRow方法。但在此之前,我需要更新行中的字段。
有没有人知道如何实现这个目标?
问题还在于它需要是通用的。应该使用具有我用自定义属性“EditableInBulk”装饰的列的每个实体类型。因此,不存在任何特定实体的持续存在。
我已经开始修改动态数据项目附带的List.aspx文件。
答案 0 :(得分:4)
好的,我们解决了。
我将解释使用Entity Framework Code First实现动态数据的通用批量编辑的不同部分。解决方案并不美观。但它确实有效。
创建一个属性(我们将其命名为EditableInBulk),您可以使用它来装饰Entity Framework POCO类中的属性。
在List.aspx中(由动态数据自动生成)将一个带有CheckBox控件的列添加到gridview,以便您可以轻松选择应该通过批量更新影响哪些行。
在GridView上的ItemDataBound上,在HeaderRow中,在相应的列中添加正确类型的DynamicControl。如果有问题的MetaColumn用EditableInBulk修饰,则只添加DynamicControl。
创建按钮或以某种方式触发批量更新。首先从HeaderRow中创建的DynamicControl中获取新值。
然后通过GridView的行迭代(使用RowType == DataRow)。确保当前行已被选为“待编辑”(在新列中找到CheckBox控件并检查值)。
获取当前行的实体ID。但首先,您必须根据页面和页面大小计算行号。否则,如果您在第一页以外的页面上,它将无效。
int index = row.DataItemIndex;
if (GridView1.PageIndex > 0)
{
index = row.DataItemIndex - (GridView1.PageIndex)*GridView1.PageSize;
}
var entityId = Convert.ToInt32(GridView1.DataKeys[index].Value.ToString());
从DataContext实例化ObjectContext。
var objectContext = ((IObjectContextAdapter) new YourProject.Data.DataContext()).ObjectContext;
获取当前列表/数据集的实体类型名称。
string entityTypeName = GridView1.DataKeyNames[0].Substring(0, GridView1.DataKeyNames[0].Count() - 2);
借助实体ID和实体类型实例化EntityKey类型的新对象。 获取将在ObjectContext
的帮助下编辑的对象var entityKey = new EntityKey(objectContext.DefaultContainerName + "." + entityTypeName + "s", GridView1.DataKeyNames[0], entityId);
注意+“s”解决方案......它有效:)(快乐/悲伤)。
var entity = objectContext.GetObjectByKey(entityKey);
在Reflection的帮助下,设置新的属性值。
PropertyInfo prop = entity.GetType().BaseType.GetProperty(newValue.Key, BindingFlags.Public | BindingFlags.Instance);
var typedValue = TypeDescriptor.GetConverter(prop.PropertyType).ConvertFrom(newValue.Value);
if (null != prop && prop.CanWrite)
{
prop.SetValue(entity, typedValue, null); }
保存新更新的实体!
objectContext.SaveChanges();
我认为还有其他几种更好的方法可以实现批量更新,但这样做有效。如果有需求,我会从我们的解决方案中添加更多代码。我只是想让你们知道有办法。