Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. why this code doesn't work ?

why this code doesn't work ?

Scheduled Pinned Locked Moved Visual Basic
question
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dilkonika
    wrote on last edited by
    #1

    Hello ! This is a code that is supposed to do a copy of an entity framework object with the childs collection that the user want.

    Imports System.Data.Objects
    Imports System.Data.Objects.DataClasses
    Imports System.Runtime.CompilerServices

    Public Module Entities
    Public Function CloneEntity(Of T As Class)(entity As T, context As ObjectContext, Optional include As List(Of IncludeEntity) = Nothing, Optional copyKeys As Boolean = False) As T
    Return CloneEntityHelper(entity, context, include, copyKeys)
    End Function

    Private Function CloneEntityHelper(Of T As Class)(entity As T, context As ObjectContext, Optional include As List(Of IncludeEntity) = Nothing, Optional copyKeys As Boolean = False) As T
    If include Is Nothing Then include = New List(Of IncludeEntity)()
    Dim myType = entity.GetType()
    Dim methodInfo = context.GetType().GetMethod("CreateObject").MakeGenericMethod(myType)
    Dim result = methodInfo.Invoke(context, Nothing)
    Dim propertyInfo = entity.GetType().GetProperties()
    For Each info In propertyInfo
    Dim attributes = info.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False).ToList()

    For Each attr As EdmScalarPropertyAttribute In attributes 
        If (Not copyKeys) AndAlso attr.EntityKeyProperty
            Continue For
        End If
    
        info.SetValue(result, info.GetValue(entity, Nothing), Nothing)
    Next
    If info.PropertyType.Name.Equals("EntityCollection\`1", StringComparison.OrdinalIgnoreCase) Then
        Dim shouldInclude = include.SingleOrDefault(Function(i) i.Name.Equals(info.Name, StringComparison.OrdinalIgnoreCase))
        If shouldInclude Is Nothing Then Continue For
        Dim relatedChildren = info.GetValue(entity, Nothing)
        Dim propertyType As Type = relatedChildren.GetType().GetGenericArguments().First()
        Dim genericType As Type = GetType(EntityCollection(Of ))
        Dim boundType = genericType.MakeGenericType(propertyType)
        Dim children = Activator.CreateInstance(boundType)
        For Each child In relatedChildren
            Dim cloneChild = CloneEntityHelper(child, context, shouldInclude.Children, shouldInclude.CopyKeys)
            children.Add(cloneChild)
        Next
        info.SetValue(result, children, Nothing)
    End If
    Next
    Return result
    End Function
    

    Public Class IncludeEntity
    Public Property Name As String
    Public Property Children As New List(Of IncludeEntity)
    Public Property CopyKeys As Boolean

    S 1 Reply Last reply
    0
    • D dilkonika

      Hello ! This is a code that is supposed to do a copy of an entity framework object with the childs collection that the user want.

      Imports System.Data.Objects
      Imports System.Data.Objects.DataClasses
      Imports System.Runtime.CompilerServices

      Public Module Entities
      Public Function CloneEntity(Of T As Class)(entity As T, context As ObjectContext, Optional include As List(Of IncludeEntity) = Nothing, Optional copyKeys As Boolean = False) As T
      Return CloneEntityHelper(entity, context, include, copyKeys)
      End Function

      Private Function CloneEntityHelper(Of T As Class)(entity As T, context As ObjectContext, Optional include As List(Of IncludeEntity) = Nothing, Optional copyKeys As Boolean = False) As T
      If include Is Nothing Then include = New List(Of IncludeEntity)()
      Dim myType = entity.GetType()
      Dim methodInfo = context.GetType().GetMethod("CreateObject").MakeGenericMethod(myType)
      Dim result = methodInfo.Invoke(context, Nothing)
      Dim propertyInfo = entity.GetType().GetProperties()
      For Each info In propertyInfo
      Dim attributes = info.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False).ToList()

      For Each attr As EdmScalarPropertyAttribute In attributes 
          If (Not copyKeys) AndAlso attr.EntityKeyProperty
              Continue For
          End If
      
          info.SetValue(result, info.GetValue(entity, Nothing), Nothing)
      Next
      If info.PropertyType.Name.Equals("EntityCollection\`1", StringComparison.OrdinalIgnoreCase) Then
          Dim shouldInclude = include.SingleOrDefault(Function(i) i.Name.Equals(info.Name, StringComparison.OrdinalIgnoreCase))
          If shouldInclude Is Nothing Then Continue For
          Dim relatedChildren = info.GetValue(entity, Nothing)
          Dim propertyType As Type = relatedChildren.GetType().GetGenericArguments().First()
          Dim genericType As Type = GetType(EntityCollection(Of ))
          Dim boundType = genericType.MakeGenericType(propertyType)
          Dim children = Activator.CreateInstance(boundType)
          For Each child In relatedChildren
              Dim cloneChild = CloneEntityHelper(child, context, shouldInclude.Children, shouldInclude.CopyKeys)
              children.Add(cloneChild)
          Next
          info.SetValue(result, children, Nothing)
      End If
      Next
      Return result
      End Function
      

      Public Class IncludeEntity
      Public Property Name As String
      Public Property Children As New List(Of IncludeEntity)
      Public Property CopyKeys As Boolean

      S Offline
      S Offline
      Sascha Lefevre
      wrote on last edited by
      #2

      Please include your class-definition of MyObject (you can omit the methods, if it has any). Did you already observe it in debug-mode?

      D 1 Reply Last reply
      0
      • S Sascha Lefevre

        Please include your class-definition of MyObject (you can omit the methods, if it has any). Did you already observe it in debug-mode?

        D Offline
        D Offline
        dilkonika
        wrote on last edited by
        #3

        Thank you ! I put some breakpoints , and I have detected that maybe the problem may be this line : Dim attributes = info.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False).ToList() . The attributes always have the Length=0 , so all the codes inside the For Each info In propertyInfo doesn;t get executed , and goes to next for each info and so at the end the result is an empty object. What can I do ? also I did another test ( maybe a stupid test but anyway ) : I put the line info.SetValue(result, info.GetValue(entity, Nothing), Nothing) after the next so outside the for loop. Now the entity is copied , but not the child that is included on inc variable. ? The code is supposed to work will any kind of classes , but anyway this are the classes where I made the tests:

        Partial Public Class Myobject
        Public Property id As Integer
        Public property name as string
        Public Overridable Property Child_list As ICollection(Of Child_list) = New HashSet(Of Child_list)
        End Class

        Partial Public Class Child_list
        Public Property id As Integer
        Public Property date1 as DateTime
        Public Property quantity as Integer
        Public Property ParentID as integer
        Public Overridable Property MyObj1 As MyObject
        End Class

        S 2 Replies Last reply
        0
        • D dilkonika

          Thank you ! I put some breakpoints , and I have detected that maybe the problem may be this line : Dim attributes = info.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False).ToList() . The attributes always have the Length=0 , so all the codes inside the For Each info In propertyInfo doesn;t get executed , and goes to next for each info and so at the end the result is an empty object. What can I do ? also I did another test ( maybe a stupid test but anyway ) : I put the line info.SetValue(result, info.GetValue(entity, Nothing), Nothing) after the next so outside the for loop. Now the entity is copied , but not the child that is included on inc variable. ? The code is supposed to work will any kind of classes , but anyway this are the classes where I made the tests:

          Partial Public Class Myobject
          Public Property id As Integer
          Public property name as string
          Public Overridable Property Child_list As ICollection(Of Child_list) = New HashSet(Of Child_list)
          End Class

          Partial Public Class Child_list
          Public Property id As Integer
          Public Property date1 as DateTime
          Public Property quantity as Integer
          Public Property ParentID as integer
          Public Overridable Property MyObj1 As MyObject
          End Class

          S Offline
          S Offline
          Sascha Lefevre
          wrote on last edited by
          #4

          Correct, the code you have there is expecting an EdmScalarPropertyAttribute on each field or property that should be copied (with the exception of _EntityCollection_s). You didn't decorate the properties of your class with this attribute, so the SetValue(..)-line was skipped. Note: I'm not familiar with EF. My following advice should make your CloneEntity-code work (or at least "almost working") but someone who knows about EF might have more to say about it. In particular, I have no idea where the id of your classes gets initialized; if you have to deal with that yourself or if it's somehow magically done for you. - Move the SetValue(..)-line back to where it was. - Put an EdmScalarPropertyAttribute on the name-property of the Myobject-class and on all properties of the Child_list-class (except id and ParentID) like so:

          Public property name as string

          - In CloneEntityHelper(..), change the string "EntityCollection`1" to "ICollection`1". - If you want to have children of children copied (to an arbitrary depth), set the Children-property of your IncludeEntity-instance to the same IncludeEntity-instance. - If you have to initialize id yourself, you will have to set it for _Myobject_s, _Child_list_s and potentially further nested objects, after the call to CloneEntity(..). - Because of the self-referencing through ParentID you will have to set ParentID for all children (and potentially children of children) to their respective parent's id after the call to CloneEntity(..) (in any case). That should be it I think..

          1 Reply Last reply
          0
          • D dilkonika

            Thank you ! I put some breakpoints , and I have detected that maybe the problem may be this line : Dim attributes = info.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False).ToList() . The attributes always have the Length=0 , so all the codes inside the For Each info In propertyInfo doesn;t get executed , and goes to next for each info and so at the end the result is an empty object. What can I do ? also I did another test ( maybe a stupid test but anyway ) : I put the line info.SetValue(result, info.GetValue(entity, Nothing), Nothing) after the next so outside the for loop. Now the entity is copied , but not the child that is included on inc variable. ? The code is supposed to work will any kind of classes , but anyway this are the classes where I made the tests:

            Partial Public Class Myobject
            Public Property id As Integer
            Public property name as string
            Public Overridable Property Child_list As ICollection(Of Child_list) = New HashSet(Of Child_list)
            End Class

            Partial Public Class Child_list
            Public Property id As Integer
            Public Property date1 as DateTime
            Public Property quantity as Integer
            Public Property ParentID as integer
            Public Overridable Property MyObj1 As MyObject
            End Class

            S Offline
            S Offline
            Sascha Lefevre
            wrote on last edited by
            #5

            Did you get it to work?

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups