Динамические данные с Entity Framework: массовое редактирование строк

#c# #entity-framework-4.1 #dynamic-data

#c# #entity-framework-4.1 #динамические данные

Вопрос:

У меня есть веб-сайт администратора продукта, который был создан с использованием 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
            }
        }
  

Я должен иметь возможность использовать метод updateRow в элементе управления GridView. Но перед этим мне нужно обновить поля внутри строки.

Кто-нибудь знает, как я мог бы этого добиться?

Дело также в том, что оно должно быть общим. Должно работать с каждым типом сущности, у которого есть столбцы, которые я украсил своим пользовательским атрибутом «EditableInBulk». Таким образом, не может быть какой-либо конкретной сущности, сохраняющейся.

Я начал изменять файл List.aspx, который поставляется с проектом Dynamic Data.

Ответ №1:

Хорошо, мы решили это.

Сначала я объясню различные части для достижения общего массового редактирования динамических данных с помощью кода Entity Framework. Решение не красивое. Но это работает.

Создайте атрибут (мы назвали его EditableInBulk), с помощью которого вы добавляете свойства в свой класс POCO Entity Framework.

В List.aspx (автоматически создаваемом с помощью Dynamic Data) добавьте столбец с элементом управления CheckBox в свой gridview, чтобы вы могли легко выбрать, какие строки должны быть затронуты массовым обновлением.

В ItemDataBound в GridView в строке заголовка добавьте DynamicControl правильного типа в соответствующий столбец. Добавляйте DynamicControl только в том случае, если рассматриваемый метаколонок украшен EditableInBulk .

Создайте кнопку или каким-либо образом запустите массовое обновление. Прежде всего извлеките новые значения из DynamicControl, которые были созданы в заголовке.

Затем выполните итерацию по строкам GridView (с RowType == DataRow). Убедитесь, что текущая строка выбрана как «подлежащая редактированию» (найдите элемент управления флажком в новом столбце и проверьте значение).

Извлеките идентификатор объекта текущей строки. Но сначала вы должны рассчитать номер строки на основе страницы и размера страницы. В противном случае это не сработает, если вы находитесь на странице, отличной от первой.

 int index = row.DataItemIndex;
if (GridView1.PageIndex > 0)
{
    index = row.DataItemIndex - (GridView1.PageIndex)*GridView1.PageSize;
}
var entityId = Convert.ToInt32(GridView1.DataKeys[index].Value.ToString());
  

Создайте экземпляр ObjectContext из вашего DataContext.

 var objectContext = ((IObjectContextAdapter) new YourProject.Data.DataContext()).ObjectContext;
  

Извлеките имя типа объекта текущего списка / набора данных.

 string entityTypeName = GridView1.DataKeyNames[0].Substring(0, GridView1.DataKeyNames[0].Count() - 2);
  

Создайте экземпляр нового объекта типа 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 amp;amp; prop.CanWrite)
                            {
                                prop.SetValue(entity, typedValue, null);                            }
  

Сохраните только что обновленный объект!

 objectContext.SaveChanges();
  

Я предполагаю, что есть несколько других лучших способов добиться массового обновления, но это работает. Если есть спрос на это, я добавлю больше кода из нашего решения. Я просто хотел, чтобы вы, ребята, знали, что есть способ.