带有实体框架的动态数据:批量编辑行

时间:2011-11-03 12:57:03

标签: c# entity-framework-4.1 dynamic-data

我有一个使用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文件。

1 个答案:

答案 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();

我认为还有其他几种更好的方法可以实现批量更新,但这样做有效。如果有需求,我会从我们的解决方案中添加更多代码。我只是想让你们知道有办法。