【问题标题】:Dynamic Data with Entity Framework: Bulk editing rows使用实体框架的动态数据:批量编辑行
【发布时间】:2011-11-03 12:57:03
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    好的,我们解决了。

    我将解释使用实体框架代码优先实现对动态数据进行通用批量编辑的不同部分。解决方案并不漂亮。但它有效。

    创建一个属性(我们将其命名为 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);
    

    借助反射,设置新的属性值。

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

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

    【讨论】:

      猜你喜欢
      • 2018-01-14
      • 2020-12-07
      • 2022-01-07
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      相关资源
      最近更新 更多