public override int SaveChanges(SaveOptions options) { foreach (ObjectStateEntry relationEntry in ObjectStateManager .GetObjectStateEntries(EntityState.Deleted) .Where(e => e.IsRelationship)) { var entry = GetEntityEntryFromRelation(relationEntry, 0); // Find representation of the relation IRelatedEnd relatedEnd = entry.RelationshipManager .GetAllRelatedEnds() .First(r => r.RelationshipSet == relationEntry.EntitySet); RelationshipType relationshipType = relatedEnd.RelationshipSet.ElementType; if (!SkipDeletion(relationshipType)) { // Now we know that model is inconsistent and entity on many side must be deleted if (!(relatedEnd is EntityReference)) // related end is many side { entry = GetEntityEntryFromRelation(relationEntry, 1); } if (entry.State != EntityState.Deleted) { context.DeleteObject(entry.Entity); } } } return(base.SaveChanges()); }
// <summary> // Sets the given value on the given <see cref="IRelatedEnd" /> which must be an // <see cref="EntityReference{TRelatedEntity}" />. // This method is setup in such a way that it can easily be used by CreateDelegate without any // dynamic code generation needed. // </summary> // <typeparam name="TRelatedEntity"> The type of the related entity. </typeparam> // <param name="entityReference"> The entity reference. </param> // <param name="value"> The value. </param> private static void SetValueOnEntityReference <TRelatedEntity>(IRelatedEnd entityReference, object value) where TRelatedEntity : class { Debug.Assert(value == null || value is TRelatedEntity); ((EntityReference <TRelatedEntity>)entityReference).Value = (TRelatedEntity)value; }
private void ExpandProperty(PropertyInfo p) { if (p.PropertyType.IsValueType || p.PropertyType == typeof(string)) { return; } string name = p.Name + "Reference"; PropertyInfo px = p.DeclaringType.GetProperty(name); if (px == null) { return; } ExpressionResult currentItem = ExpressionStack.Pop(); IRelatedEnd end = px.GetValue(currentItem.Result, null) as IRelatedEnd; end.Load(); object propertyValue = p.GetValue(currentItem.Result, null); if (ExpressionStack.Count > 0) { ExpressionStack.Peek().Result = propertyValue; } }
public static object CreateOriginalValuesObjectWithReferences(this ObjectContext context, object source) { object target = context.CreateOriginalValuesObject(source); EntityKey srcKey = ((IEntityWithKey)source).EntityKey; IEntityWithRelationships sourceWithRelationships = source as IEntityWithRelationships; if (sourceWithRelationships == null) { return(target); } foreach (var relationshipGroup in context.GetRelationshipsByRelatedEnd((IEntityWithKey)target, EntityState.Unchanged | EntityState.Deleted)) { IRelatedEnd tgtRelatedEnd = (IRelatedEnd)relationshipGroup.Key; foreach (ObjectStateEntry srcEntry in relationshipGroup) { if (tgtRelatedEnd.IsEntityReference()) { tgtRelatedEnd.SetEntityKey(srcEntry.OtherEndKey(srcKey)); } } } return(target); }
private static void SetValueOnEntityReference <TRelatedEntity>( IRelatedEnd entityReference, object value) where TRelatedEntity : class { ((EntityReference <TRelatedEntity>)entityReference).Value = (TRelatedEntity)value; }
private bool IsEntityRequiredForeignKeyEmpty(DbEntityEntry entityEntry, string errProp) { RelationshipManager relMgr = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager .GetRelationshipManager(entityEntry.Entity); IEnumerable <IRelatedEnd> relEnds = relMgr.GetAllRelatedEnds(); IRelatedEnd relEnd = relEnds.Where(r => { var elementType = (EntityTypeBase)r.RelationshipSet.ElementType; var metadataProperty = elementType.MetadataProperties.GetValue( "ReferentialConstraints", false); var referentialConstraints = ( System.Data.Entity.Core.Metadata.Edm.ReadOnlyMetadataCollection <ReferentialConstraint>)metadataProperty.Value; if (referentialConstraints.Any(constraint => { return (constraint.ToProperties.Any( t => t.Nullable == false && t.IsPrimitiveType && t.Name == errProp)); })) { return(true); } return(false); }).FirstOrDefault(); bool isEntityRequiredForeignKeyEmpty = relEnd != null; return(isEntityRequiredForeignKeyEmpty); }
/////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Gets data object context by specified relationship object. /// </summary> /// <param name="relatedEnd">IRelatedEnd object.</param> /// <returns>DataObjectContext object.</returns> public static DataObjectContext GetObjectContext(IRelatedEnd relatedEnd) { Debug.Assert(relatedEnd != null); // get ICacheableContext interface return ((ObjectQuery)relatedEnd.CreateSourceQuery()).Context as DataObjectContext; }
public static EntityKey GetEntityKey(this IRelatedEnd relatedEnd) { Debug.Assert(relatedEnd.IsEntityReference()); Type relationshipType = relatedEnd.GetType(); PropertyInfo pi = relationshipType.GetProperty("EntityKey"); return((EntityKey)pi.GetValue(relatedEnd, null)); }
public static void SetEntityKey(this IRelatedEnd relatedEnd, EntityKey key) { Debug.Assert(relatedEnd.IsEntityReference()); Type relationshipType = relatedEnd.GetType(); PropertyInfo pi = relationshipType.GetProperty("EntityKey"); pi.SetValue(relatedEnd, key, null); }
/////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Gets data object context by specified relationship object. /// </summary> /// <param name="relatedEnd">IRelatedEnd object.</param> /// <returns>DataObjectContext object.</returns> public static DataObjectContext GetObjectContext(IRelatedEnd relatedEnd) { Debug.Assert(relatedEnd != null); // get ICacheableContext interface return(((ObjectQuery)relatedEnd.CreateSourceQuery()).Context as DataObjectContext); }
private static IEnumerable <TEntity> ExtractSingle <TEntity>(IRelatedEnd relatedEnd) where TEntity : class { var valueProp = relatedEnd.GetType().GetProperty("Value"); var value = valueProp?.GetValue(relatedEnd); yield return(value as TEntity); }
private void ValidateNotDetached(string method) { if (this._relatedEnd != null) { return; } if (this.InternalEntityEntry.IsDetached) { throw Error.DbPropertyEntry_NotSupportedForDetached((object)method, (object)this.Name, (object)this.InternalEntityEntry.EntityType.Name); } this._relatedEnd = this.InternalEntityEntry.GetRelatedEnd(this.Name); }
public static bool Contains(this IRelatedEnd relatedEnd, EntityKey key) { foreach (object relatedObject in relatedEnd) { Debug.Assert(relatedObject is IEntityWithKey); if (((IEntityWithKey)relatedObject).EntityKey == key) { return(true); } } return(false); }
public void RemoveUserRoom(ChatUser user, ChatRoom room) { RunNonLazy(() => { // The hack from hell to attach the user to room.Users so delete is tracked ObjectContext context = ((IObjectContextAdapter)_db).ObjectContext; RelationshipManager manger = context.ObjectStateManager.GetRelationshipManager(room); IRelatedEnd end = manger.GetRelatedEnd("JabbR.Models.ChatRoom_Users", "ChatRoom_Users_Target"); end.Attach(user); room.Users.Remove(user); }); }
/// <summary> /// Validates that the owning entity entry is associated with an underlying /// <see /// cref="System.Data.Entity.Core.Objects.ObjectStateEntry" /> /// and /// is not just wrapping a non-attached entity. /// If the entity is not detached, then the RelatedEnd for this navigation property is obtained. /// </summary> private void ValidateNotDetached(string method) { if (_relatedEnd == null) { if (InternalEntityEntry.IsDetached) { throw Error.DbPropertyEntry_NotSupportedForDetached( method, Name, InternalEntityEntry.EntityType.Name); } _relatedEnd = InternalEntityEntry.GetRelatedEnd(Name); } }
private static IEnumerable <TEntity> ExtractValues <TEntity>(IRelatedEnd relatedEnd) where TEntity : class { if (!relatedEnd.IsLoaded) { relatedEnd.Load(); } if (relatedEnd is IEnumerable enumerable) { return(ExtractCollection <TEntity>(enumerable)); } else { return(ExtractSingle <TEntity>(relatedEnd)); } }
public static void AddReferenceToCollection( this ObjectContext oc, object target, string propertyName, object resourceToBeAdded) { EntityType entityType = oc.MetadataWorkspace.GetItem <EntityType>( target.GetType().FullName, DataSpace.CSpace); NavigationProperty navProperty = entityType.NavigationProperties[propertyName]; ObjectStateEntry entry = oc.ObjectStateManager.GetObjectStateEntry(target); IRelatedEnd relatedEnd = entry.RelationshipManager .GetRelatedEnd(navProperty.RelationshipType.Name, navProperty.ToEndMember.Name); relatedEnd.Add(resourceToBeAdded); }
private void AttachRelationOneEntity(FBEntity entity, IRelatedEnd re) { //Type t = re.GetType(); //Type eType = t.GetGenericArguments()[0]; if (re.IsLoaded) { return; } re.Load(); //RelationOneEntity rOneE = new RelationOneEntity(); //rOneE.EntityType= eType.Name; //rOneE.RelationshipName = re.RelationshipName; //rOneE.PropertyName = re.TargetRoleName; //entity.ReferencedEntity.Add(rOneE); //foreach (var item in re) //{ // FBEntity tempEntity = new FBEntity(); // tempEntity.Entity = item as EntityObject; // rOneE.FBEntity = tempEntity; // // re.Remove(item as IEntityWithRelationships); //} }
private void AttachRelationManyEntity(FBEntity entity, IRelatedEnd re) { Type t = re.GetType(); Type eType = t.GetGenericArguments()[0]; if (!re.IsLoaded) { re.Load(); } RelationManyEntity rManyE = new RelationManyEntity(); rManyE.EntityType = eType.Name; rManyE.RelationshipName = re.RelationshipName; rManyE.PropertyName = re.TargetRoleName; entity.CollectionEntity.Add(rManyE); foreach (var item in re) { FBEntity tempEntity = new FBEntity(); tempEntity.Entity = item as EntityObject; rManyE.FBEntities.Add(tempEntity); } //rManyE.FBEntities.ForEach(item => // { // try // { // IEntityWithRelationships ie = item.Entity as IEntityWithRelationships; // re.Remove(ie); // } // catch (Exception ex) // { // } // }); }
private void AttachRelationManyEntity(FBEntity entity, IRelatedEnd re) { Type t = re.GetType(); Type eType = t.GetGenericArguments()[0]; if (!re.IsLoaded) re.Load(); RelationManyEntity rManyE = new RelationManyEntity(); rManyE.EntityType = eType.Name; rManyE.RelationshipName = re.RelationshipName; rManyE.PropertyName = re.TargetRoleName; entity.CollectionEntity.Add(rManyE); foreach (var item in re) { FBEntity tempEntity = new FBEntity(); tempEntity.Entity = item as EntityObject; rManyE.FBEntities.Add(tempEntity); } //rManyE.FBEntities.ForEach(item => // { // try // { // IEntityWithRelationships ie = item.Entity as IEntityWithRelationships; // re.Remove(ie); // } // catch (Exception ex) // { // } // }); }
/// <summary> /// An asynchronous version of Load, which /// loads the related entity or entities into the related end using the specified merge option. /// </summary> /// <param name="mergeOption"> Merge option to use for loaded entity or entities. </param> /// <returns> A task representing the asynchronous operation. </returns> public static Task LoadAsync(this IRelatedEnd relatedEnd, MergeOption mergeOption) { Check.NotNull(relatedEnd, "relatedEnd"); return(relatedEnd.LoadAsync(mergeOption, CancellationToken.None)); }
// <summary> // Validates that the owning entity entry is associated with an underlying // <see // cref="System.Data.Entity.Core.Objects.ObjectStateEntry" /> // and // is not just wrapping a non-attached entity. // If the entity is not detached, then the RelatedEnd for this navigation property is obtained. // </summary> private void ValidateNotDetached(string method) { if (_relatedEnd == null) { if (InternalEntityEntry.IsDetached) { throw Error.DbPropertyEntry_NotSupportedForDetached( method, Name, InternalEntityEntry.EntityType.Name); } _relatedEnd = InternalEntityEntry.GetRelatedEnd(Name); } }
private void AttachRelationOneEntity(FBEntity entity, IRelatedEnd re) { //Type t = re.GetType(); //Type eType = t.GetGenericArguments()[0]; if (re.IsLoaded) return; re.Load(); //RelationOneEntity rOneE = new RelationOneEntity(); //rOneE.EntityType= eType.Name; //rOneE.RelationshipName = re.RelationshipName; //rOneE.PropertyName = re.TargetRoleName; //entity.ReferencedEntity.Add(rOneE); //foreach (var item in re) //{ // FBEntity tempEntity = new FBEntity(); // tempEntity.Entity = item as EntityObject; // rOneE.FBEntity = tempEntity; // // re.Remove(item as IEntityWithRelationships); //} }
public static bool TryGetObjectByKey(this ObjectContext context, ObjectStateEntry entry, IRelatedEnd relatedEnd, out object relatedEndEntity) { Debug.Assert(relatedEnd.IsEntityReference()); AssociationSetEnd associationSetEnd = (from ase in ((AssociationSet)relatedEnd.RelationshipSet).AssociationSetEnds where ase.Name.Equals(relatedEnd.TargetRoleName) select ase).First(); MetadataProperty metaDataProperty = (from mp in associationSetEnd.MetadataProperties where mp.Name.Equals("EntitySet") select mp).First(); EntitySet entitySet = (EntitySet)metaDataProperty.GetType().GetProperty("Value").GetValue(metaDataProperty); IEnumerable <EntityKeyMember> keyMembers = from km in entitySet.ElementType.KeyMembers select new EntityKeyMember(km.Name, entry.OriginalValues[km.Name]); return(context.TryGetObjectByKey(new EntityKey(entitySet.EntityContainer.Name + "." + entitySet.Name, keyMembers), out relatedEndEntity)); }
private static bool IsRelationshipParent(IRelatedEnd relatedEnd) => relatedEnd.SourceRoleName.Contains("Target");
private static bool IsRelationshipChild(IRelatedEnd relatedEnd) => relatedEnd.TargetRoleName.Contains("Target");
// // IRelatedEnd methods // public static bool IsEntityReference(this IRelatedEnd relatedEnd) { Type relationshipType = relatedEnd.GetType(); return(relationshipType.GetGenericTypeDefinition() == typeof(EntityReference <>)); }