Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As mentioned in the comments, your reflective code is not the problem, but the fact that (as the exception message explicitly tells) you are indirectly triggering a reset of one of your entity references. My advice is twofold: either modify your reflective code to ONLY copy <strong>scalar</strong> properties (strings, dates, etc..) -- alternatively ignore references and collections -- OR use serialization:</p> <pre><code>public static T CloneBySerialization&lt;T&gt;(this T source) where T : EntityObject { var serializer = new DataContractSerializer(typeof(T)); using (var ios = new MemoryStream()) { serializer.WriteObject(ios, source); ios.Seek(0, SeekOrigin.Begin); return ((T) serializer.ReadObject(ios)); } } </code></pre> <p>I must warn you that with this approach you will end up the full object graph or references. If the cloned object is an entity, <strong>YOU WILL NOT BE ABLE to use it/attach it to another context</strong>, due to the fact that references and foreign keys have been also copied, "verbatim", and this will all likely result in conflicts. The problem gets worse if you're using identity columns in keys.</p> <p>I've done a lot of magic in my previous work on these matters, and as far as cloning is concerned, the code above is all you need. All, really.</p> <p><strong>However,</strong> to fix the context issue and the usability of your cloned entity, you will have to clear-off the references and under the assumptions that you're also working with "root" entities in the ¹ ↔ * directional relational graph (I hope I am remotely clear, because the story is long) the following will also be necessary.</p> <pre><code>public static void ClearReferences(this EntityObject entity) { if (entity == null) return; foreach (var p in entity.GetType().GetProperties()) { if (p.PropertyType.IsGenericType) { var propertyType = p.PropertyType.GetGenericTypeDefinition(); if (propertyType == typeof(EntityReference&lt;&gt;)) { var reference = p.GetValue(entity) as dynamic; if (reference.EntityKey != null) { reference.EntityKey = null; ((EntityObject) reference.Value).ClearReferences(); } } if (propertyType == typeof(EntityCollection&lt;&gt;)) { var children = (p.GetValue(entity) as IEnumerable&lt;EntityObject&gt;).ToList(); // covariance foreach (var child in children) child.ClearReferences(); } } } } </code></pre> <p>So the idea is that you first clone (via serialization/deserialization), then you "purify".</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload