private static void FixupPrincipal(NavigationPropertyMetadata prop, object fixup, object source) { if (prop.TargetNavigationProperty != null && prop.TargetNavigationProperty.Multiplicity == NavigationPropertyMultiplicity.Many) { prop.TargetNavigationProperty.AddItem(fixup, source); } }
/// <summary> /// Initializes a new instance of the <see cref="ForeignKeyMappingInfo"/> class. /// </summary> /// <param name="metadata">The <see cref="PropertyMetadata"/> of the mapped property on the read entity.</param> /// <param name="metadataForSave">The <see cref="PropertyMetadata"/> of the mapped property on the for-save entity.</param> /// <param name="navPropertyMetadata">The <see cref="PropertyMetadata"/> of the navigation property associated with this foreign key.</param> /// <param name="keyPropertyMetadata">The <see cref="PropertyMetadata"/> of the key property used to query the navigation entities.</param> public ForeignKeyMappingInfo( PropertyMetadata metadata, PropertyMetadata metadataForSave, NavigationPropertyMetadata navPropertyMetadata, PropertyMetadata keyPropertyMetadata) : base(metadata, metadataForSave) { NavPropertyMetadata = navPropertyMetadata ?? throw new ArgumentNullException(nameof(navPropertyMetadata)); KeyPropertyMetadata = keyPropertyMetadata ?? throw new ArgumentNullException(nameof(keyPropertyMetadata)); KeyType = GetKeyType(keyPropertyMetadata); }
public void CopyFrom(NavigationPropertyMetadata source) { this.Target = new ClrTypeInfo(source.TargetEntity.ClrType); this.ForeignKey.Clear(); this.ForeignKey.AddRange(source.ForeignKeyProperties.Select(p => p.Dependant.Name)); this.Multiplicity = source.Multiplicity; this.Nullable = source.Nullable; this.TargetMultiplicity = source.TargetMultiplicity; this.TargetProperty = source.TargetNavigationProperty?.Name; }
private void FixupNavigationProperty(object result, NavigationPropertyMetadata navProp) { var targetEntityInfo = GetEntityInfo(navProp.TargetEntity); var key = navProp.GetForeignKeyObject(result); if (key != null) { var target = GetTrackedObjectOrDefault(targetEntityInfo, key); if (target != null && _trackingInfoProvider.GetState(target) != TrackingState.Deleted) { FillNavigationPropertyAndPrincipal(navProp, result, target); } } }
private static void FillNavigationPropertyAndPrincipal(NavigationPropertyMetadata navProp, object source, object target) { ////using (new ChangeTrackingScope(ChangeTracking.Disable, source, target)) ////{ navProp.SetValue(source, target); // das geladene Property als geladen markieren ////source.MarkNavigationPropertyAsLoaded(navProp.Name); if (navProp.TargetNavigationProperty != null) { if (navProp.TargetNavigationProperty.Multiplicity == NavigationPropertyMultiplicity.Many) { navProp.TargetNavigationProperty.AddItem(target, source); } else { navProp.TargetNavigationProperty.SetValue(target, source); // am Ziel markieren, dass es geladen ist ////target.MarkNavigationPropertyAsLoaded(navProp.TargetNavigationProperty.Name); } } }
private Func <IEnumerable <object>, IEnumerable <object>, IEnumerable <object> > CreateReverseFixupDelegate(NavigationPropertyMetadata prop) { var reverseEntityInfo = GetEntityInfo(prop.Entity); ParameterExpression trackedParameter = Expression.Parameter(typeof(IEnumerable <object>)); ParameterExpression entitiesParameter = Expression.Parameter(typeof(IEnumerable <object>)); Expression baseQuery = Expression.Call( typeof(Enumerable).GetMethod("OfType").MakeGenericMethod(reverseEntityInfo.EntityMetadata.ClrType), trackedParameter); ParameterExpression param = Expression.Parameter(reverseEntityInfo.EntityMetadata.ClrType); ParameterExpression param2 = Expression.Parameter(prop.TargetEntity.ClrType); Expression filterCondition = Expression.Equal(Expression.Property(param, prop.Name), Expression.Constant(null)); filterCondition = Expression.AndAlso( filterCondition, Expression.NotEqual( Expression.Constant(TrackingState.Deleted, typeof(TrackingState?)), Expression.Call(Expression.Constant(_trackingInfoProvider, typeof(ITrackingInfoProvider)), typeof(ITrackingInfoProvider).GetMethod("GetState"), param))); baseQuery = Expression.Call( typeof(Enumerable).GetMethods().First(p => p.Name == "Where").MakeGenericMethod(reverseEntityInfo.EntityMetadata.ClrType), baseQuery, Expression.Lambda(filterCondition, param)); Expression joinPrimary; Expression joinForeign; if (prop.Multiplicity != NavigationPropertyMultiplicity.Many && prop.TargetMultiplicity != NavigationPropertyMultiplicity.Many) { if (prop.Entity.PrimaryKeyCount == 1) { joinPrimary = Expression.Property(param2, prop.TargetEntity.GetProperties().First(p => p.IsPrimaryKey).Name); joinForeign = Expression.Property(param, prop.Entity.GetProperties().First(p => p.IsPrimaryKey).Name); } else { throw new NotImplementedException(); } } else { if (prop.ForeignKeyProperties.Count == 1) { joinPrimary = Expression.Property(param2, prop.ForeignKeyProperties.First().Principal.Name); joinForeign = Expression.Property(param, prop.ForeignKeyProperties.First().Dependant.Name); } else { // Dieser Fall existiert momentan im Datenmodel noch nicht. Betrifft zusammengesetzte ForeignKeys. throw new NotImplementedException(); } } if (joinPrimary.Type != joinForeign.Type) { joinPrimary = Expression.Convert(joinPrimary, joinForeign.Type); } var block = new List <Expression> { Expression.Assign(Expression.Property(param, prop.Name), param2) }; if (prop.TargetNavigationProperty != null) { if (prop.TargetMultiplicity == NavigationPropertyMultiplicity.Many) { var collectionType = typeof(ICollection <>).MakeGenericType(prop.Entity.ClrType); block.Add(Expression.Call(Expression.Property(param2, prop.TargetNavigationProperty.Name), collectionType.GetMethod("Add"), param)); } else { block.Add(Expression.Assign(Expression.Property(param2, prop.TargetNavigationProperty.Name), param)); } } block.Add(param); baseQuery = Expression.Call( _enumerableJoinMethod.MakeGenericMethod(param.Type, param2.Type, joinForeign.Type, param.Type), baseQuery, Expression.Call(typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(param2.Type), entitiesParameter), Expression.Lambda(joinForeign, param), Expression.Lambda(joinPrimary, param2), Expression.Lambda( Expression.Block( block), param, param2)); var lambda = Expression.Lambda <Func <IEnumerable <object>, IEnumerable <object>, IEnumerable <object> > >( baseQuery, trackedParameter, entitiesParameter); return(lambda.Compile()); }