private MaterializeAtom ReadPropertyFromRawData(ClientPropertyAnnotation property) { MaterializeAtom atom; DataServiceContext source = (DataServiceContext)base.Source; bool applyingChanges = source.ApplyingChanges; try { source.ApplyingChanges = true; string mime = null; Encoding encoding = null; Type type = property.EntityCollectionItemType ?? property.NullablePropertyType; IList results = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(new Type[] { type })); HttpProcessUtility.ReadContentType(base.ContentType, out mime, out encoding); using (Stream stream = base.GetResponseStream()) { if (property.PropertyType == typeof(byte[])) { int contentLength = (int)base.ContentLength; byte[] buffer = null; if (contentLength >= 0) { buffer = ReadByteArrayWithContentLength(stream, contentLength); } else { buffer = ReadByteArrayChunked(stream); } results.Add(buffer); property.SetValue(this.entity, buffer, this.propertyName, false); } else { StreamReader reader = new StreamReader(stream, encoding); object obj2 = (property.PropertyType == typeof(string)) ? reader.ReadToEnd() : ClientConvert.ChangeType(reader.ReadToEnd(), property.PropertyType); results.Add(obj2); property.SetValue(this.entity, obj2, this.propertyName, false); } } if (property.MimeTypeProperty != null) { property.MimeTypeProperty.SetValue(this.entity, mime, null, false); } atom = MaterializeAtom.CreateWrapper(source, results); } finally { source.ApplyingChanges = applyingChanges; } return(atom); }
internal static object ProjectionInitializeEntity(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, Type resultType, string[] properties, Func <object, object, Type, object>[] propertyValues) { if (entry.Entry == null) { throw new NullReferenceException(System.Data.Services.Client.Strings.AtomMaterializer_EntryToInitializeIsNull(resultType.FullName)); } if (!entry.EntityHasBeenResolved) { ProjectionEnsureEntryAvailableOfType(materializer, entry, resultType); } else if (!resultType.IsAssignableFrom(entry.ActualType.ElementType)) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_ProjectEntityTypeMismatch(resultType.FullName, entry.ActualType.ElementType.FullName, entry.Entry.Id)); } object resolvedObject = entry.ResolvedObject; for (int i = 0; i < properties.Length; i++) { StreamDescriptor descriptor; string propertyName = properties[i]; ClientPropertyAnnotation annotation = entry.ActualType.GetProperty(propertyName, materializer.ResponseInfo.IgnoreMissingProperties); object target = propertyValues[i](materializer, entry.Entry, expectedType); ODataProperty property = (from p in entry.Entry.Properties where p.Name == propertyName select p).FirstOrDefault <ODataProperty>(); if ((((((property == null) && (entry.NavigationLinks != null)) ? (from l in entry.NavigationLinks where l.Name == propertyName select l).FirstOrDefault <ODataNavigationLink>() : null) != null) || (property != null)) || entry.EntityDescriptor.TryGetNamedStreamInfo(propertyName, out descriptor)) { if (entry.ShouldUpdateFromPayload && (annotation.EdmProperty.Type.TypeKind() == EdmTypeKind.Entity)) { materializer.Log.SetLink(entry, annotation.PropertyName, target); } if (entry.ShouldUpdateFromPayload) { if (!annotation.IsEntityCollection) { if (!annotation.IsPrimitiveOrComplexCollection) { annotation.SetValue(resolvedObject, target, annotation.PropertyName, false); } } else { IEnumerable list = (IEnumerable)target; DataServiceQueryContinuation continuation = materializer.nextLinkTable[list]; Uri nextLink = (continuation == null) ? null : continuation.NextLinkUri; ProjectionPlan plan = (continuation == null) ? null : continuation.Plan; materializer.MergeLists(entry, annotation, list, nextLink, plan); } } else if (annotation.IsEntityCollection) { materializer.FoundNextLinkForUnmodifiedCollection(annotation.GetValue(entry.ResolvedObject) as IEnumerable); } } } return(resolvedObject); }
/// <summary> /// Gets or creates a collection property on the specified <paramref name="instance"/>. /// </summary> /// <param name="instance">Instance on which to get/create the collection.</param> /// <param name="property">Collection property on the <paramref name="instance"/>.</param> /// <param name="forLoadProperty">Is this collection being created for LoadProperty scenario.</param> /// <returns> /// The collection corresponding to the specified <paramref name="property"/>; /// never null. /// </returns> private object GetOrCreateCollectionProperty(object instance, ClientPropertyAnnotation property, bool forLoadProperty) { Debug.Assert(instance != null, "instance != null"); Debug.Assert(property != null, "property != null"); Debug.Assert(property.IsResourceSet, "property.IsEntityCollection has to be true - otherwise property isn't a collection"); // NOTE: in V1, we would have instantiated nested objects before setting them. object result; result = property.GetValue(instance); if (result == null) { Type collectionType = property.PropertyType; // For backward compatibility we need to have different strategy of collection creation b/w // LoadProperty scenario versus regular collection creation scenario. if (forLoadProperty) { if (BindingEntityInfo.IsDataServiceCollection(collectionType, this.MaterializerContext.Model)) { Debug.Assert(WebUtil.GetDataServiceCollectionOfT(property.EntityCollectionItemType) != null, "DataServiceCollection<> must be available here."); // new DataServiceCollection<property.EntityCollectionItemType>(null, TrackingMode.None) result = Activator.CreateInstance( WebUtil.GetDataServiceCollectionOfT(property.EntityCollectionItemType), null, TrackingMode.None); } else { // Try List<> first because that's what we did in V1/V2, but use the actual property type if it doesn't support List<> Type listCollectionType = typeof(List <>).MakeGenericType(property.EntityCollectionItemType); if (collectionType.IsAssignableFrom(listCollectionType)) { collectionType = listCollectionType; } result = Activator.CreateInstance(collectionType); } } else { if (DSClient.PlatformHelper.IsInterface(collectionType)) { collectionType = typeof(System.Collections.ObjectModel.Collection <>).MakeGenericType(property.EntityCollectionItemType); } result = this.CreateNewInstance(property.EdmProperty.Type, collectionType); } // Update the property value on the instance. property.SetValue(instance, result, property.PropertyName, false /* add */); } Debug.Assert(result != null, "result != null -- otherwise GetOrCreateCollectionProperty didn't fall back to creation"); return(result); }
private void ApplyItemsToCollection(MaterializerEntry entry, ClientPropertyAnnotation property, IEnumerable items, Uri nextLink, ProjectionPlan continuationPlan) { Func <LinkDescriptor, bool> predicate = null; object instance = entry.ShouldUpdateFromPayload ? GetOrCreateCollectionProperty(entry.ResolvedObject, property, null) : null; ClientEdmModel model = ClientEdmModel.GetModel(base.ResponseInfo.MaxProtocolVersion); ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(property.EntityCollectionItemType)); foreach (object obj3 in items) { if (!clientTypeAnnotation.ElementType.IsAssignableFrom(obj3.GetType())) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_EntryIntoCollectionMismatch(obj3.GetType().FullName, clientTypeAnnotation.ElementType.FullName)); } if (entry.ShouldUpdateFromPayload) { property.SetValue(instance, obj3, property.PropertyName, true); this.log.AddedLink(entry, property.PropertyName, obj3); } } if (entry.ShouldUpdateFromPayload) { this.FoundNextLinkForCollection(instance as IEnumerable, nextLink, continuationPlan); } else { this.FoundNextLinkForUnmodifiedCollection(property.GetValue(entry.ResolvedObject) as IEnumerable); } if ((this.mergeOption == MergeOption.OverwriteChanges) || (this.mergeOption == MergeOption.PreserveChanges)) { if (predicate == null) { predicate = delegate(LinkDescriptor x) { if (MergeOption.OverwriteChanges != this.mergeOption) { return(EntityStates.Added != x.State); } return(true); }; } foreach (object obj4 in (from x in base.ResponseInfo.EntityTracker.GetLinks(entry.ResolvedObject, property.PropertyName).Where <LinkDescriptor>(predicate) select x.Target).Except <object>(EnumerateAsElementType <object>(items))) { if (instance != null) { property.RemoveValue(instance, obj4); } this.log.RemovedLink(entry, property.PropertyName, obj4); } } }
private void MergeLists(MaterializerEntry entry, ClientPropertyAnnotation property, IEnumerable list, Uri nextLink, ProjectionPlan plan) { if ((entry.ShouldUpdateFromPayload && (property.NullablePropertyType == list.GetType())) && (property.GetValue(entry.ResolvedObject) == null)) { property.SetValue(entry.ResolvedObject, list, property.PropertyName, false); this.FoundNextLinkForCollection(list, nextLink, plan); foreach (object obj2 in list) { this.log.AddedLink(entry, property.PropertyName, obj2); } } else { this.ApplyItemsToCollection(entry, property, list, nextLink, plan); } }
/// <summary> /// Populates the collection property on the entry's resolved object with the given items enumerator. /// </summary> /// <param name="entry">Entry with collection to be modified.</param> /// <param name="property">Collection property on the entry.</param> /// <param name="items">Values to apply onto the collection.</param> /// <param name="nextLink">Next link for collection continuation.</param> /// <param name="continuationPlan">Projection plan for collection continuation.</param> /// <returns>Collection instance that was populated.</returns> private object PopulateCollectionProperty( MaterializerEntry entry, ClientPropertyAnnotation property, IEnumerable <object> items, Uri nextLink, ProjectionPlan continuationPlan) { Debug.Assert(entry.Entry != null || entry.ForLoadProperty, "ODataResource should be non-null except for LoadProperty"); Debug.Assert(property != null, "property != null"); Debug.Assert(items != null, "items != null"); object collection = null; ClientEdmModel edmModel = this.MaterializerContext.Model; ClientTypeAnnotation collectionType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(property.ResourceSetItemType)); if (entry.ShouldUpdateFromPayload) { collection = this.GetOrCreateCollectionProperty(entry.ResolvedObject, property, entry.ForLoadProperty); foreach (object item in items) { // Validate that item can be inserted into collection. ValidateCollectionElementTypeIsItemType(item.GetType(), collectionType.ElementType); property.SetValue(collection, item, property.PropertyName, true /* allowAdd? */); this.EntityTrackingAdapter.MaterializationLog.AddedLink(entry, property.PropertyName, item); } this.FoundNextLinkForCollection(collection as IEnumerable, nextLink, continuationPlan); } else { Debug.Assert(!entry.ForLoadProperty, "LoadProperty should always have ShouldUpdateForPayload set to true."); foreach (object item in items) { // Validate that item can be inserted into collection. ValidateCollectionElementTypeIsItemType(item.GetType(), collectionType.ElementType); } this.FoundNextLinkForUnmodifiedCollection(property.GetValue(entry.ResolvedObject) as IEnumerable); } return(collection); }
private static object GetOrCreateCollectionProperty(object instance, ClientPropertyAnnotation property, Type collectionType) { object obj2 = property.GetValue(instance); if (obj2 == null) { if (collectionType == null) { collectionType = property.PropertyType; if (collectionType.IsInterfaceEx()) { collectionType = typeof(Collection <>).MakeGenericType(new Type[] { property.EntityCollectionItemType }); } } obj2 = Activator.CreateInstance(collectionType); property.SetValue(instance, obj2, property.PropertyName, false); } return(obj2); }
private MaterializeAtom ReadPropertyFromRawData(ClientPropertyAnnotation property) { DataServiceContext context = (DataServiceContext)this.Source; bool merging = context.ApplyingChanges; try { context.ApplyingChanges = true; // if this is the data property for a media entry, what comes back // is the raw value (no markup) #if ASTORIA_OPEN_OBJECT object openProps = null; #endif string mimeType = null; Encoding encoding = null; Type elementType = property.EntityCollectionItemType ?? property.NullablePropertyType; IList results = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)); ContentTypeUtil.ReadContentType(this.ContentType, out mimeType, out encoding); using (Stream responseStream = this.GetResponseStream()) { // special case byte[], and for everything else let std conversion kick-in if (property.PropertyType == typeof(byte[])) { int total = checked ((int)this.ContentLength); byte[] buffer = null; if (total >= 0) { buffer = LoadPropertyResult.ReadByteArrayWithContentLength(responseStream, total); } else { buffer = LoadPropertyResult.ReadByteArrayChunked(responseStream); } results.Add(buffer); #if ASTORIA_OPEN_OBJECT property.SetValue(this.entity, buffer, this.propertyName, ref openProps, false); #else property.SetValue(this.entity, buffer, this.propertyName, false); #endif } else { // responseStream will disposed, StreamReader doesn't need to dispose of it. StreamReader reader = new StreamReader(responseStream, encoding); object convertedValue = property.PropertyType == typeof(string) ? reader.ReadToEnd() : ClientConvert.ChangeType(reader.ReadToEnd(), property.PropertyType); results.Add(convertedValue); #if ASTORIA_OPEN_OBJECT property.SetValue(this.entity, convertedValue, this.propertyName, ref openProps, false); #else property.SetValue(this.entity, convertedValue, this.propertyName, false); #endif } } #if ASTORIA_OPEN_OBJECT Debug.Assert(openProps == null, "These should not be set in this path"); #endif if (property.MimeTypeProperty != null) { // an implication of this 3rd-arg-null is that mime type properties cannot be open props #if ASTORIA_OPEN_OBJECT property.MimeTypeProperty.SetValue(this.entity, mimeType, null, ref openProps, false); Debug.Assert(openProps == null, "These should not be set in this path"); #else property.MimeTypeProperty.SetValue(this.entity, mimeType, null, false); #endif } return(MaterializeAtom.CreateWrapper(context, results)); } finally { context.ApplyingChanges = merging; } }
private MaterializeAtom ReadPropertyFromAtom(ClientPropertyAnnotation property) { DataServiceContext context = (DataServiceContext)this.Source; bool merging = context.ApplyingChanges; try { context.ApplyingChanges = true; // store the results so that they can be there in the response body. Type elementType = property.IsEntityCollection ? property.EntityCollectionItemType : property.NullablePropertyType; IList results = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)); DataServiceQueryContinuation continuation = null; // elementType.ElementType has Nullable stripped away, use nestedType for materializer using (MaterializeAtom materializer = this.GetMaterializer(this.plan)) { Debug.Assert(materializer != null, "materializer != null -- otherwise GetMaterializer() returned null rather than empty"); #if ASTORIA_OPEN_OBJECT object openProperties = null; #endif // when SetLink to null, we cannot get materializer because have no-content response. if (materializer.IsNoContentResponse() && property.GetValue(entity) != null && context.MergeOption != MergeOption.AppendOnly && context.MergeOption != MergeOption.NoTracking) { property.SetValue(this.entity, null, propertyName, false); } else { foreach (object child in materializer) { if (property.IsEntityCollection) { results.Add(child); } else if (property.IsPrimitiveOrEnumOrComplexCollection) { Debug.Assert(property.PropertyType.IsAssignableFrom(child.GetType()), "Created instance for storing collection items has to be compatible with the actual one."); // Collection materialization rules requires to clear the collection if not null or set the property first and then add the collection items object collectionInstance = property.GetValue(this.entity); if (collectionInstance == null) { // type of child has been resolved as per rules for collections so it is the correct type to instantiate collectionInstance = Activator.CreateInstance(child.GetType()); // allowAdd is false - we need to assign instance as the new property value property.SetValue(this.entity, collectionInstance, this.propertyName, false /* allowAdd? */); } else { // Clear existing collection property.ClearBackingICollectionInstance(collectionInstance); } foreach (var collectionItem in (IEnumerable)child) { Debug.Assert(property.PrimitiveOrComplexCollectionItemType.IsAssignableFrom(collectionItem.GetType()), "Type of materialized collection items have to be compatible with the type of collection items in the actual collection property."); property.AddValueToBackingICollectionInstance(collectionInstance, collectionItem); } results.Add(collectionInstance); } else { #if ASTORIA_OPEN_OBJECT property.SetValue(this.entity, child, this.propertyName, ref openProperties, false); #else // it is either primitive type, complex type or 1..1 navigation property so we just allow setting the value but not adding. property.SetValue(this.entity, child, this.propertyName, false); results.Add(child); #endif } } } continuation = materializer.GetContinuation(null); } return(MaterializeAtom.CreateWrapper(context, results, continuation)); } finally { context.ApplyingChanges = merging; } }
private void MaterializeResolvedEntry(MaterializerEntry entry, bool includeLinks) { ClientTypeAnnotation actualType = entry.ActualType; if (!actualType.IsEntityType) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidNonEntityType(actualType.ElementTypeName)); } ODataMaterializer.MaterializeDataValues(actualType, entry.Properties, base.ResponseInfo.IgnoreMissingProperties); if (entry.NavigationLinks != null) { foreach (ODataNavigationLink link in entry.NavigationLinks) { ClientPropertyAnnotation annotation2 = actualType.GetProperty(link.Name, true); if (annotation2 != null) { ValidatePropertyMatch(annotation2, link, base.ResponseInfo, true); } } } if (includeLinks && (entry.NavigationLinks != null)) { foreach (ODataNavigationLink link2 in entry.NavigationLinks) { MaterializerNavigationLink link3 = MaterializerNavigationLink.GetLink(link2); if (link3 != null) { ClientPropertyAnnotation annotation3 = actualType.GetProperty(link2.Name, base.ResponseInfo.IgnoreMissingProperties); if (annotation3 != null) { if (link3.Feed != null) { this.ApplyFeedToCollection(entry, annotation3, link3.Feed, includeLinks); } else if (link3.Entry != null) { MaterializerEntry entry2 = link3.Entry; if (entry2.Entry != null) { this.Materialize(entry2, annotation3.PropertyType, includeLinks); } if (entry.ShouldUpdateFromPayload) { annotation3.SetValue(entry.ResolvedObject, entry2.ResolvedObject, link2.Name, true); this.log.SetLink(entry, annotation3.PropertyName, entry2.ResolvedObject); } } } } } } foreach (ODataProperty property in entry.Properties) { if (!(property.Value is ODataStreamReferenceValue)) { ClientPropertyAnnotation annotation4 = actualType.GetProperty(property.Name, base.ResponseInfo.IgnoreMissingProperties); if ((annotation4 != null) && entry.ShouldUpdateFromPayload) { ValidatePropertyMatch(annotation4, property, base.ResponseInfo, true); ODataMaterializer.ApplyDataValue(actualType, property, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo, entry.ResolvedObject); } } } ApplyLinkProperties(actualType, entry); if (base.ResponseInfo.HasReadingEntityHandlers) { ODataMaterializer.ReadingEntityInfo annotation = entry.Entry.GetAnnotation <ODataMaterializer.ReadingEntityInfo>(); base.ResponseInfo.FireReadingEntityEvent(entry.ResolvedObject, annotation.EntryPayload, annotation.BaseUri); } }
/// <summary> /// Implementation of Read/>. /// </summary> /// <returns> /// Return value of Read/> /// </returns> protected override bool ReadImplementation() { // Eagerly materialize the entire collection of objects into the items cache in LoadProperty scenario. if (this.iteration == 0) { while (base.ReadImplementation()) { this.items.Add(this.currentValue); } ClientPropertyAnnotation property = this.responseInfo.Property; EntityDescriptor entityDescriptor = this.responseInfo.EntityDescriptor; object entity = entityDescriptor.Entity; MaterializerEntry entry = MaterializerEntry.CreateEntryForLoadProperty( entityDescriptor, this.Format, this.responseInfo.MergeOption != MergeOption.NoTracking); entry.ActualType = this.responseInfo.Model.GetClientTypeAnnotation(this.responseInfo.Model.GetOrCreateEdmType(entity.GetType())); if (property.IsEntityCollection) { this.EntryValueMaterializationPolicy.ApplyItemsToCollection( entry, property, this.items, this.CurrentFeed != null ? this.CurrentFeed.NextPageLink : null, this.MaterializeEntryPlan, this.responseInfo.IsContinuation); } else { Debug.Assert(this.items.Count <= 1, "Expecting 0 or 1 element."); object target = this.items.Count > 0 ? this.items[0] : null; Debug.Assert(property.EdmProperty.Type.TypeKind() == EdmTypeKind.Entity, "Must be entity typed property if not an entity collection property."); this.EntityTrackingAdapter.MaterializationLog.SetLink(entry, property.PropertyName, target); // Singleton entity property property.SetValue(entity, target, property.PropertyName, false); } // Apply the materialization log. this.ApplyLogToContext(); // Clear the log after applying it. this.ClearLog(); } // Read object from the already loaded items cache. if (this.items.Count > this.iteration) { this.currentValue = this.items[this.iteration]; this.iteration++; return(true); } else { this.currentValue = null; return(false); } }
protected static void ApplyDataValue(ClientTypeAnnotation type, ODataProperty property, bool ignoreMissingProperties, System.Data.Services.Client.ResponseInfo responseInfo, object instance) { ClientPropertyAnnotation annotation = type.GetProperty(property.Name, ignoreMissingProperties); if (annotation != null) { if (annotation.IsPrimitiveOrComplexCollection) { if (property.Value == null) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Collection_NullCollectionNotSupported(property.Name)); } if (property.Value is string) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_MixedTextWithComment); } if (property.Value is ODataComplexValue) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidCollectionItem(property.Name)); } object obj2 = annotation.GetValue(instance); if (obj2 == null) { obj2 = CreateCollectionInstance(property, annotation.PropertyType, responseInfo); annotation.SetValue(instance, obj2, property.Name, false); } else { annotation.ClearBackingICollectionInstance(obj2); } ApplyCollectionDataValues(property, ignoreMissingProperties, responseInfo, obj2, annotation.PrimitiveOrComplexCollectionItemType, new Action <object, object>(annotation.AddValueToBackingICollectionInstance)); } else { object obj3 = property.Value; ODataComplexValue value2 = obj3 as ODataComplexValue; if ((obj3 != null) && (value2 != null)) { if (!annotation.EdmProperty.Type.IsComplex()) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_ExpectingSimpleValue); } bool flag = false; ClientEdmModel model = ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion); ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(annotation.PropertyType)); object obj4 = annotation.GetValue(instance); if (obj4 == null) { obj4 = clientTypeAnnotation.CreateInstance(); flag = true; } MaterializeDataValues(clientTypeAnnotation, value2.Properties, ignoreMissingProperties); ApplyDataValues(clientTypeAnnotation, value2.Properties, ignoreMissingProperties, responseInfo, obj4); if (flag) { annotation.SetValue(instance, obj4, property.Name, true); } } else { MaterializePrimitiveDataValue(annotation.NullablePropertyType, property); annotation.SetValue(instance, property.GetMaterializedValue(), property.Name, true); } } } }
private MaterializeAtom ReadPropertyFromAtom(EntityDescriptor box, ClientPropertyAnnotation property) { MaterializeAtom atom2; DataServiceContext source = (DataServiceContext)base.Source; bool applyingChanges = source.ApplyingChanges; try { source.ApplyingChanges = true; bool flag2 = EntityStates.Deleted == box.State; bool instanceCreated = false; object instance = null; if (property.IsEntityCollection) { instance = this.GetCollectionInstance(property, out instanceCreated); } Type type = property.IsEntityCollection ? property.EntityCollectionItemType : property.NullablePropertyType; IList results = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(new Type[] { type })); DataServiceQueryContinuation continuation = null; using (MaterializeAtom atom = base.GetMaterializer(this.plan)) { bool flag4 = property.EdmProperty.PropertyKind == EdmPropertyKind.Navigation; int num = 0; foreach (object obj3 in atom) { if (property.IsEntityCollection) { property.SetValue(instance, obj3, this.propertyName, true); results.Add(obj3); } else if (property.IsPrimitiveOrComplexCollection) { object obj4 = property.GetValue(this.entity); if (obj4 == null) { obj4 = Activator.CreateInstance(obj3.GetType()); property.SetValue(this.entity, obj4, this.propertyName, false); } else { property.ClearBackingICollectionInstance(obj4); } foreach (object obj5 in (IEnumerable)obj3) { property.AddValueToBackingICollectionInstance(obj4, obj5); } results.Add(obj4); } else { property.SetValue(this.entity, obj3, this.propertyName, false); results.Add(obj3); } num++; if (((obj3 != null) && (MergeOption.NoTracking != atom.MergeOptionValue)) && flag4) { if (flag2) { source.DeleteLink(this.entity, this.propertyName, obj3); } else { source.AttachLink(this.entity, this.propertyName, obj3, atom.MergeOptionValue); } } } continuation = atom.GetContinuation(null); Util.SetNextLinkForCollection(property.IsEntityCollection ? instance : this.entity, continuation); } if (instanceCreated) { property.SetValue(this.entity, instance, this.propertyName, false); } atom2 = MaterializeAtom.CreateWrapper(source, results, continuation); } finally { source.ApplyingChanges = applyingChanges; } return(atom2); }