Чтобы упростить повторное использование элементов управления, мы создали решение с тремя отдельными проектами: библиотека элементов управления, клиент Silverlight и серверная часть ASP.NET. В управляющей библиотеке нет ссылок на сгенерированные RIA Services классы моделей данных, поэтому, когда ей необходимо с ней взаимодействовать, мы используем отражение.
До сих пор это работало нормально, но я столкнулся с проблемой. У меня есть элемент управления DataGrid, где пользователь может выбрать строку, нажать кнопку «Удалить», и он должен удалить объект из коллекции. В классе DataGrid у меня есть следующий метод:
private void RemoveEntity(Entity entity)
{
// Use reflection to remove the item from the collection
Type sourceType = typeof(System.Windows.Ria.EntityCollection<>);
Type genericType = sourceType.MakeGenericType(entity.GetType());
System.Reflection.MethodInfo removeMethod = genericType.GetMethod("Remove");
removeMethod.Invoke(this._dataGrid.ItemsSource, new object[] { entity });
// Equivalent to: ('Foo' derives from Entity)
// EntityCollection<Foo> ec;
// ec.Remove(entity);
}
Это работает на стороне клиента, но в доменной службе при методе Submit () возникает следующая ошибка:
"Оператор UPDATE конфликтует с
ограничение FOREIGN KEY
"********". Конфликт произошел в
база данных "********", таблица "********",
колонка "********". Заявление имеет
было прекращено. "
Одна вещь, которую я заметил, это то, что метод службы UpdateFoo () вызывается вместо метода DeleteFoo () в доменной службе. Дальнейшая проверка показывает, что объект входит в набор изменений ModifiedEntities вместо набора изменений RemovedEntities. Я не знаю, в этом ли проблема, но это не так.
Любая помощь будет оценена, спасибо,
UPDATE
Я определил, что проблема определенно связана с вызовом отражения метода EntityCollection.Remove (). По какой-то причине его вызов приводит к изменению свойства EntityState объекта на EntityState.Modified вместо EntityState.Deleted, как и должно быть.
Даже если я пытаюсь удалить из коллекции, полностью обойдя DataGrid, я получаю точно такую же проблему:
Entity selectedEntity = this.DataContext.GetType().GetProperty("SelectedEntity").GetValue(this.DataContext, null) as Entity;
object foo = selectedEntity.GetType().GetProperty("Foo").GetValue(selectedEntity, null);
foo.GetType().InvokeMember("Remove", BindingFlags.InvokeMethod, null, foo, new object[] { entity });
В качестве теста я попытался изменить метод доменной службы UpdateFoo () для реализации удаления, и он успешно работал для удаления объекта. Это указывает на то, что вызов службы RIA работает правильно, он просто вызывает неправильный метод (обновление вместо удаления.)
public void UpdateFoo(Foo currentFoo)
{
// Original update implementation
//if ((currentFoo.EntityState == EntityState.Detached))
// this.ObjectContext.AttachAsModified(currentFoo, this.ChangeSet.GetOriginal(currentFoo));
// Delete implementation substituted in
Foo foo = this.ChangeSet.GetOriginal(currentFoo);
if ((foo.EntityState == EntityState.Detached))
this.ObjectContext.Attach(foo);
this.ObjectContext.DeleteObject(foo);
}