Beispiel #1
0
 private bool HasAssociationChanged(MetaAssociation assoc, TrackedObject item)
 {
     if (item.Original != null && item.Current != null)
     {
         if (assoc.ThisMember.StorageAccessor.HasAssignedValue(item.Current) ||
             assoc.ThisMember.StorageAccessor.HasLoadedValue(item.Current)
             )
         {
             return(this.GetOtherItem(assoc, item.Current) != this.GetOtherItem(assoc, item.Original));
         }
         else
         {
             object[] currentFKs = CommonDataServices.GetForeignKeyValues(assoc, item.Current);
             object[] originaFKs = CommonDataServices.GetForeignKeyValues(assoc, item.Original);
             for (int i = 0, n = currentFKs.Length; i < n; i++)
             {
                 if (!object.Equals(currentFKs[i], originaFKs[i]))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
Beispiel #2
0
 internal RelationComposer(ParameterExpression parameter, MetaAssociation association, Expression otherSouce, Expression parameterReplacement)
 {
     this.parameter            = parameter ?? throw Error.ArgumentNull(nameof(parameter));
     this.association          = association ?? throw Error.ArgumentNull(nameof(association));
     this.otherSouce           = otherSouce ?? throw Error.ArgumentNull(nameof(otherSouce));
     this.parameterReplacement = parameterReplacement ?? throw Error.ArgumentNull(nameof(parameterReplacement));
 }
        /// <summary>
        /// Returns a unique association name for the specified MetaAssociation
        /// </summary>
        /// <param name="metaAssociation">A <see cref="MetaAssociation"/>.</param>
        /// <returns>A <see cref="String"/> containing the association name.</returns>
        private string GetAssociationName(MetaAssociation metaAssociation)
        {
            lock (this._associationNameMap)
            {
                // We need a unique key for this association, so we use the MetaAssociation
                // itself. In the case of bi-directional associations, we use the FK side.
                if (!metaAssociation.IsForeignKey && metaAssociation.OtherMember != null)
                {
                    metaAssociation = metaAssociation.OtherMember.Association;
                }

                string associationName = null;
                if (!this._associationNameMap.TryGetValue(metaAssociation, out associationName))
                {
                    // names are always formatted non-FK side type name followed by FK side type name
                    // For example, the name for both ends of the PurchaseOrder/PurchaseOrderDetail
                    // association will be PurchaseOrder_PurchaseOrderDetail
                    if (metaAssociation.IsForeignKey)
                    {
                        associationName = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", metaAssociation.OtherType.Name, metaAssociation.ThisMember.DeclaringType.Name);
                    }
                    else
                    {
                        associationName = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", metaAssociation.ThisMember.DeclaringType.Name, metaAssociation.OtherType.Name);
                    }

                    associationName = TypeDescriptionContextBase.MakeUniqueName(associationName, this._associationNameMap.Values);
                    this._associationNameMap[metaAssociation] = associationName;
                }

                return(associationName);
            }
        }
        private static ResolvedJoinInfo CreateResolvedJoinInfo(
            SqlEntityExpression originatingEntity, MetaAssociation metaAssociation, IResolvedTableInfo joinedTableInfo)
        {
            var leftColumn = ResolveMember(originatingEntity, metaAssociation.ThisKey);

            // If needed, implement by using compounds (NewExpressions with named arguments, see NamedExpression.CreateNewExpressionWithNamedArguments.)
            if (metaAssociation.OtherKey.Count > 1)
            {
                throw new NotSupportedException(
                          string.Format(
                              "Associations with more than one column are currently not supported. ({0}.{1})",
                              originatingEntity.Type,
                              metaAssociation.OtherMember.Name));
            }

            var otherKey    = metaAssociation.OtherKey[0];
            var rightColumn = new SqlColumnDefinitionExpression(
                otherKey.Type,
                joinedTableInfo.TableAlias,
                otherKey.MappedName,
                otherKey.IsPrimaryKey);

            var joinCondition = ConversionUtility.MakeBinaryWithOperandConversion(ExpressionType.Equal, leftColumn, rightColumn, false, null);

            return(new ResolvedJoinInfo(joinedTableInfo, joinCondition));
        }
Beispiel #5
0
        private IEnumerable <string> GetDropForeignKeyCommands(MetaTable metaTable)
        {
            var metaType = metaTable.RowType;

            foreach (var member in metaType.DataMembers)
            {
                if (member.IsDeclaredBy(metaType) && member.IsAssociation)
                {
                    MetaAssociation association   = member.Association;
                    var             stringBuilder = new StringBuilder();
                    var             mappedName    = member.MappedName;
                    if (mappedName == member.Name)
                    {
                        mappedName = string.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}", SqlIdentifier.UnquoteIdentifier(metaType.Table.TableName),
                                                   SqlIdentifier.UnquoteIdentifier(member.Name));
                    }

                    var command = string.Format("SELECT count(*) FROM RDB$RELATION_CONSTRAINTS WHERE UPPER(RDB$CONSTRAINT_NAME) = '{0}'", mappedName.ToUpper());
                    var result  = sqlProvider.services.Context.ExecuteQuery <int>(command).Single();
                    if (result == 0)
                    {
                        continue;
                    }

                    command = "ALTER TABLE {0}" + Environment.NewLine + "  DROP CONSTRAINT {1}";
                    var tableName = association.IsForeignKey ? metaType.Table.TableName : association.OtherType.Table.TableName;
                    yield return(stringBuilder.AppendFormat(command, new object[]
                    {
                        tableName,
                        mappedName,
                    }).ToString());
                }
            }
        }
Beispiel #6
0
        // Ensure the the member and foreign keys are nulled so that after trackedInstance is deleted,
        // the object does not appear to be associated with the other side anymore. This prevents the deleted object
        // from referencing objects still in the cache, but also will prevent the related object from being implicitly loaded
        private static void ClearForeignKeysHelper(MetaAssociation assoc, object trackedInstance)
        {
            Debug.Assert(assoc.IsForeignKey, "Foreign key clearing should only happen on foreign key side of the association.");
            Debug.Assert(assoc.ThisMember.IsAssociation, "Expected ThisMember of an association to always be an association.");

            // If this member is one of our deferred loaders, and it does not already have a value, explicitly set the deferred source to
            // null so that when we set the association member itself to null later, it doesn't trigger an implicit load.
            // This is only necessary if the value has not already been assigned or set, because otherwise we won't implicitly load anyway when the member is accessed.
            MetaDataMember thisMember = assoc.ThisMember;

            if (thisMember.IsDeferred &&
                !(thisMember.StorageAccessor.HasAssignedValue(trackedInstance) || thisMember.StorageAccessor.HasLoadedValue(trackedInstance)))
            {
                // If this is a deferred member, set the value directly in the deferred accessor instead of going
                // through the normal member accessor, so that we don't trigger an implicit load.
                thisMember.DeferredSourceAccessor.SetBoxedValue(ref trackedInstance, null);
            }

            // Notify the object that the relationship should be considered deleted.
            // This allows the object to do its own fixup even when we can't do it automatically.
            thisMember.MemberAccessor.SetBoxedValue(ref trackedInstance, null);

            // Also set the foreign key values to null if possible
            for (int i = 0, n = assoc.ThisKey.Count; i < n; i++)
            {
                MetaDataMember thisKey = assoc.ThisKey[i];
                if (thisKey.CanBeNull)
                {
                    thisKey.StorageAccessor.SetBoxedValue(ref trackedInstance, null);
                }
            }
        }
        private void SetAssociationKeyInfo(MetaAssociation association)
        {
            DLinqColumnProvider column = (DLinqColumnProvider)FromColumn;

            List <string> foreignKeyNames = new List <string>();

            int count = column.Member.Association.ThisKey.Count;

            for (int i = 0; i < count; i++)
            {
                MetaDataMember thisKeyMetaDataMember  = column.Member.Association.ThisKey[i];
                MetaDataMember otherKeyMetaDataMember = column.Member.Association.OtherKey[i];

                DLinqColumnProvider thisEntityMemberComponent = FindColumn(column.Table, thisKeyMetaDataMember.Name);

                if (ShouldRemoveThisAssociation(association))
                {
                    column.ShouldRemove = true;
                    return;
                }

                foreignKeyNames.Add(thisEntityMemberComponent.Name);

                if (thisEntityMemberComponent.IsPrimaryKey)
                {
                    IsPrimaryKeyInThisTable = true;
                }
                if (association.IsForeignKey)
                {
                    thisEntityMemberComponent.IsForeignKeyComponent = true;
                }
            }

            ForeignKeyNames = new ReadOnlyCollection <string>(foreignKeyNames);
        }
Beispiel #8
0
 public Association(MetaAssociation metaAssociation, Guid associationId, Guid itemSourceId, Guid itemTargetId, string associationName)
     : base(metaAssociation, associationId)
 {
     this.itemSourceId = itemSourceId;
     this.itemTargetId = itemTargetId;
     this.associationName = associationName;
 }
Beispiel #9
0
 internal void Add(MetaAssociation assoc, TrackedObject from, TrackedObject to)
 {
     if (!associations.TryGetValue(assoc, out var value))
     {
         value = new Dictionary <TrackedObject, TrackedObject>();
         associations.Add(assoc, value);
     }
     value.Add(from, to);
 }
Beispiel #10
0
 internal TrackedObject this[MetaAssociation assoc, TrackedObject from] {
     get {
         if (associations.TryGetValue(assoc, out var value) && value.TryGetValue(from, out var value2))
         {
             return(value2);
         }
         return(null);
     }
 }
Beispiel #11
0
        internal static object[] GetForeignKeyValues(MetaAssociation association, object instance)
        {
            var list = new List <object>();

            foreach (MetaDataMember member in association.ThisKey)
            {
                list.Add(member.MemberAccessor.GetBoxedValue(instance));
            }
            return(list.ToArray());
        }
Beispiel #12
0
        internal static object[] GetForeignKeyValues(MetaAssociation association, object instance)
        {
            List <object> keyValues = new List <object>();

            foreach (MetaDataMember mm in association.ThisKey)
            {
                keyValues.Add(mm.MemberAccessor.GetBoxedValue(instance));
            }
            return(keyValues.ToArray());
        }
Beispiel #13
0
            internal void Add(MetaAssociation assoc, TrackedObject from, TrackedObject to)
            {
                Dictionary <TrackedObject, TrackedObject> dictionary;

                if (!this.associations.TryGetValue(assoc, out dictionary))
                {
                    dictionary = new Dictionary <TrackedObject, TrackedObject>();
                    this.associations.Add(assoc, dictionary);
                }
                dictionary.Add(from, to);
            }
Beispiel #14
0
            internal void Add(MetaAssociation assoc, TrackedObject from, TrackedObject to)
            {
                Dictionary <TrackedObject, TrackedObject> pairs;

                if (!associations.TryGetValue(assoc, out pairs))
                {
                    pairs = new Dictionary <TrackedObject, TrackedObject>();
                    associations.Add(assoc, pairs);
                }
                pairs.Add(from, to);
            }
Beispiel #15
0
 // Properties
 internal TrackedObject this[MetaAssociation assoc, TrackedObject from]
 {
     get
     {
         Dictionary <TrackedObject, TrackedObject> dictionary;
         TrackedObject obj2;
         if (this.associations.TryGetValue(assoc, out dictionary) && dictionary.TryGetValue(from, out obj2))
         {
             return(obj2);
         }
         return(null);
     }
 }
        /// <summary>
        /// Returns an AssociationAttribute for the specified association member
        /// </summary>
        /// <param name="member">The metadata member corresponding to the association member</param>
        /// <returns>The Association attribute</returns>
        public System.ComponentModel.DataAnnotations.AssociationAttribute CreateAssociationAttribute(MetaDataMember member)
        {
            MetaAssociation metaAssociation = member.Association;

            string associationName = this.GetAssociationName(metaAssociation);
            string thisKey         = TypeDescriptionContextBase.FormatMemberList(metaAssociation.ThisKey.Select(p => p.Name));
            string otherKey        = TypeDescriptionContextBase.FormatMemberList(metaAssociation.OtherKey.Select(p => p.Name));

            System.ComponentModel.DataAnnotations.AssociationAttribute assocAttrib = new System.ComponentModel.DataAnnotations.AssociationAttribute(associationName, thisKey, otherKey);
            assocAttrib.IsForeignKey = metaAssociation.IsForeignKey;

            return(assocAttrib);
        }
        public DLinqAssociationProvider(DLinqColumnProvider column)
        {
            FromColumn = column;

            MetaAssociation association = column.Member.Association;

            SetOtherEndOfAssociation(association);

            SetDirection(association);
            Debug.Assert(Direction != AssociationDirection.ManyToMany, "Many to Many is not supported by Linq to SQL");

            SetAssociationKeyInfo(association);
        }
Beispiel #18
0
        private IEnumerable <string> GetCreateForeignKeyCommands(MetaType metaType)
        {
            foreach (var member in metaType.DataMembers)
            {
                if (member.IsDeclaredBy(metaType) && member.IsAssociation)
                {
                    MetaAssociation association = member.Association;
                    if (association.IsForeignKey)
                    {
                        var stringBuilder = new StringBuilder();
                        var thisKey       = BuildKey(association.ThisKey);
                        var otherKey      = BuildKey(association.OtherKey);
                        var otherTable    = association.OtherType.Table.TableName;
                        var mappedName    = member.MappedName;
                        if (mappedName == member.Name)
                        {
                            mappedName = string.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}",
                                                       new object[] { QuoteCompoundIdentifier(metaType.Table.TableName), QuoteIdentifier(member.Name) });
                        }
                        var command = "ALTER TABLE {0}" + Environment.NewLine + "  ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3}({4})";

                        string deleteRule  = " NO ACTION";
                        var    otherMember = association.OtherMember;
                        if (otherMember != null)
                        {
                            if (association.DeleteRule != null)
                            {
                                deleteRule = association.DeleteRule;
                            }
                            //if (deleteRule != null)
                            //{
                            //    command += Environment.NewLine + "  ON DELETE " + deleteRule;
                            //}
                        }
                        stringBuilder.AppendFormat(command, new object[]
                        {
                            QuoteCompoundIdentifier(metaType.Table.TableName),
                            QuoteIdentifier(mappedName),
                            thisKey,
                            QuoteCompoundIdentifier(otherTable),
                            otherKey
                        });
                        //ON DELETE NO ACTION
                        stringBuilder.AppendLine();
                        stringBuilder.AppendLine("ON DELETE" + deleteRule);
                        stringBuilder.AppendLine("ON UPDATE NO ACTION");
                        yield return(stringBuilder.ToString());
                    }
                }
            }
        }
Beispiel #19
0
 internal TrackedObject this[MetaAssociation assoc, TrackedObject from] {
     get {
         Dictionary <TrackedObject, TrackedObject> pairs;
         if (associations.TryGetValue(assoc, out pairs))
         {
             TrackedObject to;
             if (pairs.TryGetValue(from, out to))
             {
                 return(to);
             }
         }
         return(null);
     }
 }
        private void SetOtherEndOfAssociation(MetaAssociation association)
        {
            DLinqTableProvider     entityMemberParentEntity = (DLinqTableProvider)FromColumn.Table;
            DLinqDataModelProvider parentEntityDataContext  = (DLinqDataModelProvider)entityMemberParentEntity.DataModel;

            if (association.OtherMember != null)
            {
                ToColumn = parentEntityDataContext.ColumnLookup[(PropertyInfo)association.OtherMember.Member];
            }
            else
            {
                ToTable = ((DLinqDataModelProvider)FromColumn.Table.DataModel).DLinqTables.Single(tp => tp.EntityType == association.OtherType.Type);
            }
        }
Beispiel #21
0
 internal Expression GetDataMemberQuery(MetaDataMember member, Expression[] keyValues)
 {
     if (member == null)
     {
         throw Error.ArgumentNull("member");
     }
     if (keyValues == null)
     {
         throw Error.ArgumentNull("keyValues");
     }
     if (member.IsAssociation)
     {
         MetaAssociation association = member.Association;
         Type            rootType    = association.ThisMember.DeclaringType.InheritanceRoot.Type;
         Expression      thisSource  = Expression.Constant(context.GetTable(rootType));
         if (rootType != association.ThisMember.DeclaringType.Type)
         {
             thisSource = Expression.Call(typeof(Enumerable), "Cast", new Type[] { association.ThisMember.DeclaringType.Type }, thisSource);
         }
         Expression thisInstance = Expression.Call(typeof(Enumerable), "FirstOrDefault", new Type[] { association.ThisMember.DeclaringType.Type },
                                                   System.Data.Linq.SqlClient.Translator.WhereClauseFromSourceAndKeys(thisSource, association.ThisKey.ToArray(), keyValues)
                                                   );
         Expression otherSource = Expression.Constant(context.GetTable(association.OtherType.InheritanceRoot.Type));
         if (association.OtherType.Type != association.OtherType.InheritanceRoot.Type)
         {
             otherSource = Expression.Call(typeof(Enumerable), "Cast", new Type[] { association.OtherType.Type }, otherSource);
         }
         Expression expr = System.Data.Linq.SqlClient.Translator.TranslateAssociation(
             this.context, association, otherSource, keyValues, thisInstance
             );
         return(expr);
     }
     else
     {
         Expression          query       = this.GetObjectQuery(member.DeclaringType, keyValues);
         Type                elementType = System.Data.Linq.SqlClient.TypeSystem.GetElementType(query.Type);
         ParameterExpression p           = Expression.Parameter(elementType, "p");
         Expression          e           = p;
         if (elementType != member.DeclaringType.Type)
         {
             e = Expression.Convert(e, member.DeclaringType.Type);
         }
         Expression mem = (member.Member is PropertyInfo)
             ? Expression.Property(e, (PropertyInfo)member.Member)
             : Expression.Field(e, (FieldInfo)member.Member);
         LambdaExpression selector = Expression.Lambda(mem, p);
         return(Expression.Call(typeof(Queryable), "Select", new Type[] { elementType, selector.Body.Type }, query, selector));
     }
 }
 private void SetDirection(MetaAssociation association)
 {
     if (association.IsMany)
     {
         Direction = AssociationDirection.OneToMany;
     }
     else if (association.OtherMember == null || association.OtherMember.Association.IsMany)
     {
         // there might not be the other member if this is a one-sided association
         Direction = AssociationDirection.ManyToOne;
     }
     else
     {
         Direction = AssociationDirection.OneToOne;
     }
 }
Beispiel #23
0
        private static IEnumerable <String> GetCreateForeignKeyCommands(MetaType type)
        {
            string tableName = type.Table.TableName;

            foreach (MetaDataMember mm in type.DataMembers)
            {
                if (mm.IsDeclaredBy(type) && mm.IsAssociation)
                {
                    MetaAssociation assoc = mm.Association;
                    if (assoc.IsForeignKey)
                    {
                        StringBuilder sb         = new StringBuilder();
                        string        thisKey    = BuildKey(assoc.ThisKey);
                        string        otherKey   = BuildKey(assoc.OtherKey);
                        string        otherTable = assoc.OtherType.Table.TableName;
                        string        name;
                        name = mm.MappedName;
                        if (name == mm.Name)
                        {
                            name = String.Format(Globalization.CultureInfo.InvariantCulture, "FK_{0}_{1}", tableName, mm.Name);
                        }
                        string cmd = "ALTER TABLE {0}" + Environment.NewLine + "  ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3}({4})";
                        //In DLinq we put the constraint on the child object (which triggers the behavior when deleted),
                        //but in SQL it is part of the parent constraint (the parent row gets changed / deleted to satisfy the constraint)
                        MetaDataMember otherMember = mm.Association.OtherMember;
                        if (otherMember != null)
                        {
                            string delConstr = otherMember.Association.DeleteRule;
                            if (delConstr != null)
                            {
                                cmd += Environment.NewLine + "  ON DELETE " + delConstr;
                            }
                        }
                        sb.AppendFormat(cmd,
                                        SqlIdentifier.QuoteCompoundIdentifier(tableName),
                                        SqlIdentifier.QuoteIdentifier(name),
                                        SqlIdentifier.QuoteCompoundIdentifier(thisKey),
                                        SqlIdentifier.QuoteCompoundIdentifier(otherTable),
                                        SqlIdentifier.QuoteCompoundIdentifier(otherKey));
                        yield return(sb.ToString());
                    }
                }
            }
        }
Beispiel #24
0
        /// <summary>
        /// Creates the explicit join method call.
        /// </summary>
        /// <param name="member">
        /// The member.
        /// </param>
        /// <param name="objectMetaType">
        /// Type of the object meta.
        /// </param>
        /// <param name="selector">
        /// The selector.
        /// </param>
        /// <returns>
        /// Explicit join method call expression
        /// </returns>
        private Expression CreateExplicitJoinMethodCall(MemberExpression member, MetaType objectMetaType, MethodInfo selector)
        {
            MetaAssociation association = objectMetaType.Associations.Where(a => a.ThisMember.Member == member.Member).SingleOrDefault();

            Expression visitedMemberExpression = this.Visit(member.Expression);

            var thisSideKeyExpression =
                Expression.Convert(
                    Expression.Property(visitedMemberExpression, association.ThisKey.Single().Member as PropertyInfo),
                    typeof(object));

            var thisPropertyExpression = Expression.Constant(association.OtherKey.Single().Member, typeof(PropertyInfo));

            var repositoryConst = Expression.Constant(this.IndexesCache);

            var explicitJoinMethodCallExpression = Expression.Call(repositoryConst, selector, thisPropertyExpression, thisSideKeyExpression);

            return(explicitJoinMethodCallExpression);
        }
Beispiel #25
0
        public void Many_To_One()
        {
            MetaType metaType = db.Configuration.Model.GetMetaType(typeof(Model.EmployeeTerritory));

            Assert.AreEqual(2, metaType.Associations.Count);

            MetaAssociation assoc = metaType.Associations[1];

            Assert.IsFalse(assoc.IsMany);
            Assert.IsTrue(assoc.OtherKeyIsPrimaryKey);

            Assert.AreEqual(typeof(Model.EmployeeTerritory), assoc.ThisMember.DeclaringType.Type);
            Assert.AreEqual(nameof(Model.EmployeeTerritory.Employee), assoc.ThisMember.Name);
            Assert.AreEqual(typeof(Model.Employee), assoc.ThisMember.Type);

            Assert.AreEqual(typeof(Model.Employee), assoc.OtherMember.DeclaringType.Type);
            Assert.AreEqual(nameof(Model.Employee.EmployeeTerritories), assoc.OtherMember.Name);
            Assert.AreEqual(typeof(Collection <Model.EmployeeTerritory>), assoc.OtherMember.Type);
        }
Beispiel #26
0
        private static void ClearForeignKeysHelper(MetaAssociation assoc, object trackedInstance)
        {
            var thisMember = assoc.ThisMember;

            if (thisMember.IsDeferred && !thisMember.StorageAccessor.HasAssignedValue(trackedInstance) && !thisMember.StorageAccessor.HasLoadedValue(trackedInstance))
            {
                thisMember.DeferredSourceAccessor.SetBoxedValue(ref trackedInstance, null);
            }
            thisMember.MemberAccessor.SetBoxedValue(ref trackedInstance, null);
            var i = 0;

            for (var count = assoc.ThisKey.Count; i < count; i++)
            {
                var metaDataMember = assoc.ThisKey[i];
                if (metaDataMember.CanBeNull)
                {
                    metaDataMember.StorageAccessor.SetBoxedValue(ref trackedInstance, null);
                }
            }
        }
Beispiel #27
0
        internal Expression GetDataMemberQuery(MetaDataMember member, Expression[] keyValues)
        {
            if (member == null)
            {
                throw Error.ArgumentNull("member");
            }
            if (keyValues == null)
            {
                throw Error.ArgumentNull("keyValues");
            }
            if (member.IsAssociation)
            {
                MetaAssociation association = member.Association;
                Type            type        = association.ThisMember.DeclaringType.InheritanceRoot.Type;
                Expression      source      = Expression.Constant(Context.GetTable(type));
                if (type != association.ThisMember.DeclaringType.Type)
                {
                    source = Expression.Call(typeof(Enumerable), "Cast", new[] { association.ThisMember.DeclaringType.Type }, new[] { source });
                }
                Expression thisInstance = Expression.Call(typeof(Enumerable), "FirstOrDefault", new[] { association.ThisMember.DeclaringType.Type }, new[] { Translator.WhereClauseFromSourceAndKeys(source, association.ThisKey.ToArray(), keyValues) });
                Expression otherSource  = Expression.Constant(Context.GetTable(association.OtherType.InheritanceRoot.Type));
                if (association.OtherType.Type != association.OtherType.InheritanceRoot.Type)
                {
                    otherSource = Expression.Call(typeof(Enumerable), "Cast", new[] { association.OtherType.Type }, new[] { otherSource });
                }
                return(Translator.TranslateAssociation(Context, association, otherSource, keyValues, thisInstance));
            }
            Expression          objectQuery = GetObjectQuery(member.DeclaringType, keyValues);
            Type                elementType = TypeSystem.GetElementType(objectQuery.Type);
            ParameterExpression expression6 = Expression.Parameter(elementType, "p");
            Expression          expression7 = expression6;

            if (elementType != member.DeclaringType.Type)
            {
                expression7 = Expression.Convert(expression7, member.DeclaringType.Type);
            }
            Expression       body        = (member.Member is PropertyInfo) ? Expression.Property(expression7, (PropertyInfo)member.Member) : Expression.Field(expression7, (FieldInfo)member.Member);
            LambdaExpression expression9 = Expression.Lambda(body, new[] { expression6 });

            return(Expression.Call(typeof(Queryable), "Select", new[] { elementType, expression9.Body.Type }, new[] { objectQuery, expression9 }));
        }
Beispiel #28
0
 private bool HasAssociationChanged(MetaAssociation assoc, TrackedObject item)
 {
     if (item.Original != null && item.Current != null)
     {
         if (assoc.ThisMember.StorageAccessor.HasAssignedValue(item.Current) || assoc.ThisMember.StorageAccessor.HasLoadedValue(item.Current))
         {
             return(GetOtherItem(assoc, item.Current) != GetOtherItem(assoc, item.Original));
         }
         var foreignKeyValues  = CommonDataServices.GetForeignKeyValues(assoc, item.Current);
         var foreignKeyValues2 = CommonDataServices.GetForeignKeyValues(assoc, item.Original);
         var i = 0;
         for (var num = foreignKeyValues.Length; i < num; i++)
         {
             if (!object.Equals(foreignKeyValues[i], foreignKeyValues2[i]))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Beispiel #29
0
 internal static Expression TranslateAssociation(DataContext context, MetaAssociation association, Expression otherSource, Expression[] keyValues, Expression thisInstance)
 {
     if (association == null)
     {
         throw Error.ArgumentNull("association");
     }
     if (keyValues == null)
     {
         throw Error.ArgumentNull("keyValues");
     }
     if (context.LoadOptions != null)
     {
         LambdaExpression associationSubquery = context.LoadOptions.GetAssociationSubquery(association.ThisMember.Member);
         if (associationSubquery != null)
         {
             var composer = new RelationComposer(associationSubquery.Parameters[0], association, otherSource, thisInstance);
             return(composer.Visit(associationSubquery.Body));
         }
     }
     return(WhereClauseFromSourceAndKeys(otherSource, association.OtherKey.ToArray <MetaDataMember>(), keyValues));
 }
Beispiel #30
0
        private TrackedObject GetOtherItem(MetaAssociation assoc, object instance)
        {
            if (instance == null)
            {
                return(null);
            }
            object obj = null;

            if (assoc.ThisMember.StorageAccessor.HasAssignedValue(instance) || assoc.ThisMember.StorageAccessor.HasLoadedValue(instance))
            {
                obj = assoc.ThisMember.MemberAccessor.GetBoxedValue(instance);
            }
            else if (assoc.OtherKeyIsPrimaryKey)
            {
                var foreignKeyValues = CommonDataServices.GetForeignKeyValues(assoc, instance);
                obj = services.GetCachedObject(assoc.OtherType, foreignKeyValues);
            }
            if (obj == null)
            {
                return(null);
            }
            return(tracker.GetTrackedObject(obj));
        }
Beispiel #31
0
 internal RelationComposer(ParameterExpression parameter, MetaAssociation association, Expression otherSouce, Expression parameterReplacement)
 {
     if (parameter == null)
     {
         throw Error.ArgumentNull("parameter");
     }
     if (association == null)
     {
         throw Error.ArgumentNull("association");
     }
     if (otherSouce == null)
     {
         throw Error.ArgumentNull("otherSouce");
     }
     if (parameterReplacement == null)
     {
         throw Error.ArgumentNull("parameterReplacement");
     }
     this.parameter            = parameter;
     this.association          = association;
     this.otherSouce           = otherSouce;
     this.parameterReplacement = parameterReplacement;
 }