Чтобы упростить повторное использование элементов управления, мы создали решение с тремя отдельными проектами: библиотека элементов управления, клиент 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. Не знаю, проблема ли в этом, но это не кажется правильным.
Любая помощь будет оценена, спасибо,
ОБНОВИТЬ
Я определил, что проблема определенно связана с вызовом отражения метода 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 работает правильно, просто вызывается неправильный метод (Update вместо Delete).
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);
}