none
Связанные DataGrid'ы, EDM, DomainService, Silverlight RRS feed

  • Общие обсуждения

  • Имеются два связанных DataGrid'а и, соответственно, операции добавление, удаление, копирование строк.

    Коллекции сущностей связаны через DataContext DataGrid'ов, для внешней таблицы - DomainDataSourceView, для связанной таблицы - CollectionViewSource.

    Работает все, кроме удаления строк в связанной таблице. Строки из датагрида удаляются, но... EntityState становится не deleted, a modified. И если попытаться сохранить изменения, то оно заявит, что изменено ключевое поле, это запрещено. Если добавить новую строку во внешнюю таблицу (с ключом 0 по умолчанию), тут "удаленные" строки и обнаружатся в связанном датагриде с полем внешнего ключа = 0. Т.е. вместо удаления выбранных строк в связанной таблице обнуляется поле внешнего ключа. И все. При сохранении ошибка.

    Нужны идеи, как с этим справиться.

    	''' Добавление строк
    	Public Sub AddItems(datagrid As Windows.Controls.DataGrid)
    		Dim SelectedItemsCount As Integer = datagrid.SelectedItems.Count
    		Dim item As Object = datagrid.SelectedItem
    		For i As Integer = 1 To SelectedItemsCount
    			If TypeOf datagrid.DataContext Is DomainDataSourceView Then datagrid.DataContext.Add(Activator.CreateInstance(item.GetType))
    			If TypeOf datagrid.DataContext Is CollectionViewSource Then datagrid.DataContext.Source.Add(Activator.CreateInstance(item.GetType))
    		Next
    	End Sub
    
    	''' Удаление выбранных строк из DataGrid
    	Public Sub DelItems(datagrid As Windows.Controls.DataGrid)
    		Dim SelectedItemsList As New List(Of Object)
    		For Each item As Object In datagrid.SelectedItems
    			SelectedItemsList.Add(item)
    		Next
    		For Each item As Object In SelectedItemsList
    			If TypeOf datagrid.DataContext Is DomainDataSourceView Then datagrid.DataContext.REMOVE(item)
    			If TypeOf datagrid.DataContext Is CollectionViewSource Then datagrid.DataContext.Source.REMOVE(item)
    		Next
    	End Sub
    
    	''' Копирование объекта Item
    	Public Function ItemCopy(ByRef currentitem As Object, ByRef copyitem As Object)
    	End Function
    
    	''' Копирование выбранных строк в DataGrid
    	Public Sub CopyItems(datagrid As Windows.Controls.DataGrid)
    		Dim SelectedItems As New List(Of Object)
    		For Each item As Object In datagrid.SelectedItems
    			SelectedItems.Add(item)
    		Next
    		For Each item As Object In SelectedItems
    			Dim copy As Object = Activator.CreateInstance(item.GetType)
    			If TypeOf datagrid.DataContext Is DomainDataSourceView Then datagrid.DataContext.Add(copy)
    			If TypeOf datagrid.DataContext Is CollectionViewSource Then datagrid.DataContext.Source.Add(copy)
    			ItemCopy(item, copy)
    		Next
    	End Sub
    

    ova
    15 июля 2011 г. 0:44

Все ответы

  • datagrid.DataContext.REMOVE(item)

    REMOVE ваша функция? Что вы в ней делаете? Ощущение, что вы не используете MVVM, а работаете напрямую с ORM.

    16 июля 2011 г. 8:34
  • Функции Add и Remove наследуются через DataContext DataGrid'a. Если DataGrid внешний (ведущий), то наследование от DomainDataSourceView, если DataGrid связанный (ведомый), то наследование от CollectionViewSource.,

    Что касается архитектуры - не совсем понял, что значит "используете". Если имеется ввиду использование готового шаблона MVVM, то нет, не использую. Если же речь идет о концепции MVVM, то откровенно говоря - не задумывался MVVM это, или МVP, или MVC. На самом деле - это БД - EntityDataModel - DomainService (c метаданными, отдельный на две связанные таблицы) - RIA (один контрол RIA, два DataGid'a). В случае связанных таблиц, генерится один DomainDataSource, который биндится к внешнему DataGrid'у, а также генерится CollectionViewSource, который биндится к связанному DataGrid'у. 

    Собственно, практически все в соответствии с http://msdn.microsoft.com/ru-ru/library/ee796241(v=VS.91).aspx

    А дальше используются функции Add и Remove, наследуемые от DomainDataSourceView, CollectionViewSource соответственно, где они, в свою очередь, также наследуются от Collection.

    Выше приведенный код чуть-чуть усложнен циклами, поскольку предполагается обработка нескольких строк. Функционально значимый код следующий:

    ''' Добавление строки
    	Public Sub AddItems(datagrid As Windows.Controls.DataGrid)
    		Dim item As Object = datagrid.SelectedItem
    		If TypeOf datagrid.DataContext Is DomainDataSourceView Then datagrid.DataContext.Add(Activator.CreateInstance(item.GetType))
    		If TypeOf datagrid.DataContext Is CollectionViewSource Then datagrid.DataContext.Source.Add(Activator.CreateInstance(item.GetType))
    	End Sub
    
    ''' Удаление строки из DataGrid
    	Public Sub DelItems(datagrid As Windows.Controls.DataGrid)
    		Dim item As Object = datagrid.SelectedItem
    		If TypeOf datagrid.DataContext Is DomainDataSourceView Then datagrid.DataContext.Remove(item)
    		If TypeOf datagrid.DataContext Is CollectionViewSource Then datagrid.DataContext.Source.Remove(item)
    	End Sub
    
    
    Вероятно, Вас смутил капс на функции REMOVE? Это случайность :)

     


    ova

    16 июля 2011 г. 12:47
  • Классы метаданных:

     

    <MetadataTypeAttribute(GetType(Class1.Class1Metadata))> _
    Partial Public Class Class1
     
     Friend NotInheritable Class Class1Metadata
     
     Private Sub New()
     MyBase.New
     End Sub
    
    		Public Property id1 As Integer
    		Public Property name As String
    
    		<Include()>
    		Public Property Class2 As EntityCollection(Of Class2)
    
    
    	End Class
    End Class
    
    <MetadataTypeAttribute(GetType(Class2.Class2Metadata))> _
    Partial Public Class Class2
     
     Friend NotInheritable Class Class2Metadata
     
     Private Sub New()
     MyBase.New
     End Sub
     
    		Public Property id2 As Integer
    		Public Property id1 As Integer
    		Public Property name As String
    		Public Property field1 As String
    		Public Property field2 As String
    		Public Property Class1 As Class1
    
     End Class
    End Class
    


     

    DomainService:

     

    <EnableClientAccess()> _
    Public Class MyDomainService
    	Inherits LinqToEntitiesDomainService(Of dbHealthEntities)
    
    	Public Function GetClass2() As IQueryable(Of Class2)
    		Return Me.ObjectContext.Class2
    	End Function
     
     Public Sub InsertClass2(ByVal Class2 As Class2)
    		If ((Class2.EntityState = EntityState.Detached) = False) Then Me.ObjectContext.ObjectStateManager.ChangeObjectState(Class2, EntityState.Added)
    		Else
    			Me.ObjectContext.Class2.AddObject(Class2)
    		End If
     End Sub
     
     Public Sub UpdateClass2(ByVal currentClass2 As Class2)
     Me.ObjectContext.Class2.AttachAsModified(currentClass2, Me.ChangeSet.GetOriginal(currentClass2))
     End Sub
     
    	Public Sub DeleteClass2(ByVal Class2 As Class2)
    		If Not (Class2.EntityState = EntityState.Detached) Then
    			Me.ObjectContext.ObjectStateManager.ChangeObjectState(Class2, EntityState.Deleted)
    		Else
    			Me.ObjectContext.Class2.Attach(Class2)
    			Me.ObjectContext.Class2.DeleteObject(Class2)
    		End If
    	End Sub
     
     Public Function GetClass1() As IQueryable(Of Class1)
    		Return Me.ObjectContext.Class1.Include("Class2").OrderBy(Function(c) c.id)
    	End Function
     
     Public Sub InsertClass1(ByVal Class1 As Class1)
    		If ((Class1.EntityState = EntityState.Detached) = False) Then
    			Me.ObjectContext.ObjectStateManager.ChangeObjectState(Class1, EntityState.Added)
    		Else
    			Me.ObjectContext.Class1.AddObject(Class1)
    		End If
     End Sub
     
     Public Sub UpdateClass1(ByVal currentClass1 As Class1)
     Me.ObjectContext.Class1.AttachAsModified(currentClass1, Me.ChangeSet.GetOriginal(currentClass1))
     End Sub
     
     Public Sub DeleteClass1(ByVal Class1 As Class1)
    		If ((Class1.EntityState = EntityState.Detached) = False) Then
    			Me.ObjectContext.ObjectStateManager.ChangeObjectState(Class1, EntityState.Deleted)
    		Else
    			Me.ObjectContext.Class1.Attach(Class1)
    			Me.ObjectContext.Class1.DeleteObject(Class1)
    		End If
     End Sub
    End Class
    
    


    ova


    16 июля 2011 г. 13:07
  • Уважаемый пользователь!

    В вашей теме отсутствует активность в течение последних 5 дней. При отсутствии каких-либо действий в течение 2 последующих дней, тема будет переведена в разряд обсуждений. Вы можете возобновить дискуссию, просто оставив сообщение в данной теме


    Для связи [mail]
    20 июля 2011 г. 7:05
  • Попробуйте сделать проверку CanRemove у контекста. На первый взгляд все должно работать.
    22 июля 2011 г. 11:32