Example #1
0
 private static void FixupPrincipal(NavigationPropertyMetadata prop, object fixup, object source)
 {
     if (prop.TargetNavigationProperty != null && prop.TargetNavigationProperty.Multiplicity == NavigationPropertyMultiplicity.Many)
     {
         prop.TargetNavigationProperty.AddItem(fixup, source);
     }
 }
Example #2
0
 /// <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);
 }
Example #3
0
 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;
 }
Example #4
0
        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);
                }
            }
        }
Example #5
0
        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);
                }
            }
        }
Example #6
0
        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());
        }