39922

Entity Framework : Why this code doesn't work

Question:

I'm using Entity Framework 6.0, DbContext. I'm using this method to copy an object and some related children:

Imports System.Data.Objects Imports System.Data.Objects.DataClasses Imports System.Runtime.CompilerServices Public Module Entities <Extension()> 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 Public Sub New(propertyName As String, ParamArray childNodes() As String) Name = propertyName Children = childNodes.Select(Function(n) new IncludeEntity(n)).ToList() End Sub End Class End Module

Now I'm using the code like below :

Dim litm, newitm As New MyObject Dim inc = New List(Of IncludeEntity)() inc.Add(New IncludeEntity("Child_list")) litm=context.MyObjects.FirstOrDefault newitm = litm.CloneEntity(CType(context, Entity.Infrastructure.IObjectContextAdapter).ObjectContext,include:=inc)

The code is executed without errors, but nothing is copied, so newitm is empty.

I have inspected the code and found that this line on the CloneEntity function :

Dim myType = entity.GetType()

Is producing a strange type.

I'm expecting that the type will be of MyObject type, but instead this return :

MyObject_F2FFE64DA472EB2B2BDF7E143DE887D3845AD9D1731FD3107937062AC0C2E4BB

This line too :

Dim result = methodInfo.Invoke(context, Nothing)

produces the same strange type.

I don't know if this is the problem, but this is the only strange thing I have noticed.

Can you help me to find out why this code doesn't work?

Thank you!

Answer1:

Entity framework, like many other ORMs will build a proxy type for your entities so that it can intercept calls to:

<ul><li>Lazy load the contents of any collection contained as properties within your entity, when you access those collection properties.</li> <li>Detect that you have made changes to the properties of an instance as part of dirty checking, so that it will know which objects are dirty and need to be saved to the database when you invoke SaveChanges.</li> </ul>

Refer for example to <a href="https://stackoverflow.com/questions/9501471/ef-returning-proxy-class-instead-of-actual-entity" rel="nofollow">EF returning proxy class instead of actual entity</a> or <a href="https://msdn.microsoft.com/en-us/data/jj592886.aspx" rel="nofollow">Working with Proxies</a>.

If you want to find out the underlying type of your entity that is wrapped by the proxy, i.e. the one that would match with the type you are looking for (e.g. MyObject), you can do that using a method in the object context:

var underlyingType = ObjectContext.GetObjectType(entity.GetType());

Recommend

  • Finding the attributes on the properties of an instance of a class
  • AudioUnitInitialize failed with error code 1701737535 'ent?' after alarm interruption
  • Convert generic T into System.Enum
  • Custom Enum Parse
  • Get overridden property attribute
  • get address name from WCF service
  • What is the idiomatic way to handle/unwrap nested Result types?
  • Windows Phone 8 - enums & DataAnnotations
  • Getting two different GUIDs for an Assembly
  • Include external XML ENTITIES using SYSTEM while resolving path with $ENV variable
  • SMTP Mail Sending Issue : com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Unable to relay
  • How to get location with dbid in 2D
  • Upload blob in Azure using BlobOutputStream
  • Deep cloning objects
  • Looping through Generic Class's collection property
  • Apache Flink integration with Elasticsearch
  • Filling out Object Properties with default values Recursive
  • converting Twilio sms body to a string - encoding error for @ symbol
  • How to map childs/parent class with petapoco?
  • Avoid Rendering “No Data Available in the table” in Datatables
  • Objective C IBOutlets
  • nhibernate queries SubQueryExpression
  • Showing spinner for Rails 3 UJS gets Type error
  • Laravel lmutator $this->attributes return 'Undefined index: id'
  • JFreeChart & iText : black image when creating pdf
  • Retrieve Facebook Account Information in ios 6
  • CSS Grid, position absolute an element in a css grid item: IMPOSSIBLE
  • OCILogon during Grace Period - ORA-28002
  • css background images not always displayed
  • Why are “sc.addFile” and “spark-submit --files” not distributing a local file to all workers?
  • Dynamically add UI elements to StackPanel after button pressed
  • triggering user space with kernel
  • how to get data attributes of dynamically generated element
  • sweetalert2 inputoptions from file in select example
  • New Firebase failed: First argument must be a valid firebase URL and the path can't contain “.”
  • JSON encode and decode on PHP
  • Building Qt project for C++11 standard
  • ListItem.Attributes.Add not working
  • How to change the font size of a single index for UISegmentedControl?
  • How to rebase a series of branches?