コード例 #1
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static NotSupportedException ColumnGreaterThanMaxLengthNotSupported(object p0, object p1)
 {
     return(NotSupported(EntityRes.GetString(EntityRes.ColumnGreaterThanMaxLengthNotSupported, new[] { p0, p1 })));
 }
コード例 #2
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static InvalidOperationException DeleteDatabaseNotAllowedWithinTransaction()
 {
     return(InvalidOperation(EntityRes.GetString(EntityRes.DeleteDatabaseNotAllowedWithinTransaction)));
 }
コード例 #3
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static ArgumentException DeleteDatabaseWithOpenConnection()
 {
     return(Argument(EntityRes.GetString(EntityRes.DeleteDatabaseWithOpenConnection)));
 }
コード例 #4
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static NotSupportedException ComputedColumnsNotSupportedException()
 {
     return(NotSupported(EntityRes.GetString(EntityRes.ComputedColumnsNotSupported)));
 }
コード例 #5
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static NotSupportedException ServerGeneratedGuidKeyNotSupportedException(object p0)
 {
     return(NotSupported(EntityRes.GetString(EntityRes.ServerGeneratedGuidKeyNotSupported, new[] { p0 })));
 }
コード例 #6
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static NotSupportedException CollateInOrderByNotSupportedException()
 {
     return(NotSupported(EntityRes.GetString(EntityRes.CollateInOrderByNotSupported)));
 }
        protected override void DbCreateDatabase(DbConnection connection, int?timeOut, StoreItemCollection storeItemCollection)
        {
            Check.NotNull(connection, "connection");
            Check.NotNull(storeItemCollection, "storeItemCollection");

            // Validate that connection is a SqlCeConnection.
            ValidateConnection(connection);

            // We don't support create/delete database operations inside a transaction as they can't be rolled back.
            if (InTransactionScope())
            {
                throw ADP1.CreateDatabaseNotAllowedWithinTransaction();
            }

            if (_isLocalProvider)
            {
                var engine = new SqlCeEngine(DbInterception.Dispatch.Connection.GetConnectionString(connection, new DbInterceptionContext()));
                engine.CreateDatabase();
                engine.Dispose();
            }
            else
            {
                try
                {
                    Type rdpType;

                    // If we are working with RDP, then we will need to invoke the APIs through reflection.
                    var engine = RemoteProviderHelper.GetRemoteSqlCeEngine(
                        DbInterception.Dispatch.Connection.GetConnectionString(connection, new DbInterceptionContext()),
                        out rdpType);
                    Debug.Assert(engine != null);

                    // Invoke the required method on SqlCeEngine.
                    var mi = rdpType.GetMethod("CreateDatabase", new[] { typeof(int?) });
                    Debug.Assert(mi != null);

                    // We will pass 'timeout' to RDP, this will be used as timeout period for connecting and executing on TDSServer.
                    mi.Invoke(engine, new object[] { timeOut });
                }
                catch (Exception e)
                {
                    throw e.GetBaseException();
                }
            }

            // Create the command object depending on provider.
            var command = connection.CreateCommand();

            // Create the command texts from StoreItemCollection.
            var commandTextCollection = SqlDdlBuilder.CreateObjectsScript(storeItemCollection, false);

            DbTransaction transaction = null;

            var interceptionContext = new DbInterceptionContext();

            try
            {
                // Open the connection.
                DbInterception.Dispatch.Connection.Open(connection, interceptionContext);

                // Open a transaction and attach to the command.
                transaction         = DbInterception.Dispatch.Connection.BeginTransaction(connection, new BeginTransactionInterceptionContext());
                command.Transaction = transaction;

                // Execute each statement.
                foreach (var text in commandTextCollection)
                {
                    command.CommandText = text;
                    DbInterception.Dispatch.Command.NonQuery(command, new DbCommandInterceptionContext());
                }

                // Commit the transaction.
                DbInterception.Dispatch.Transaction.Commit(transaction, interceptionContext);
            }
            catch (Exception e)
            {
                if (transaction != null)
                {
                    // Rollback the transaction.
                    DbInterception.Dispatch.Transaction.Rollback(transaction, interceptionContext);
                }

                // Throw IOE with SqlCeException embedded as inner exception.
                throw new InvalidOperationException(EntityRes.GetString(EntityRes.IncompleteDatabaseCreation), e);
            }
            finally
            {
                // Close connection and cleanup objects.
                if (command != null)
                {
                    command.Dispose();
                }
                if (transaction != null)
                {
                    DbInterception.Dispatch.Transaction.Dispose(transaction, interceptionContext);
                }
                if (connection != null)
                {
                    DbInterception.Dispatch.Connection.Close(connection, interceptionContext);
                }
            }
        }
コード例 #8
0
 protected override string GetLocalizedString(string value)
 {
     return(EntityRes.GetString(value));
 }
コード例 #9
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static string Update_NotSupportedServerGenKey(object p0)
 {
     return(EntityRes.GetString(EntityRes.Update_NotSupportedServerGenKey, new[] { p0 }));
 }
コード例 #10
0
        // <summary>
        // Returns error context in the format [[errorContextInfo, ]line ddd, column ddd].
        // Returns empty string if errorPosition is less than 0 and errorContextInfo is not specified.
        // </summary>
        internal static string FormatErrorContext(
            string commandText,
            int errorPosition,
            string errorContextInfo,
            bool loadErrorContextInfoFromResource,
            out int lineNumber,
            out int columnNumber)
        {
            Debug.Assert(errorPosition > -1, "position in input stream cannot be < 0");
            Debug.Assert(errorPosition <= commandText.Length, "position in input stream cannot be greater than query text size");

            if (loadErrorContextInfoFromResource)
            {
                errorContextInfo = !String.IsNullOrEmpty(errorContextInfo) ? EntityRes.GetString(errorContextInfo) : String.Empty;
            }

            //
            // Replace control chars and newLines for single representation characters
            //
            var sb = new StringBuilder(commandText.Length);

            for (var i = 0; i < commandText.Length; i++)
            {
                var c = commandText[i];
                if (CqlLexer.IsNewLine(c))
                {
                    c = '\n';
                }
                else if ((Char.IsControl(c) || Char.IsWhiteSpace(c)) &&
                         ('\r' != c))
                {
                    c = ' ';
                }
                sb.Append(c);
            }
            commandText = sb.ToString().TrimEnd(new[] { '\n' });

            //
            // Compute line and column
            //
            var queryLines = commandText.Split(new[] { '\n' }, StringSplitOptions.None);

            for (lineNumber = 0, columnNumber = errorPosition;
                 lineNumber < queryLines.Length && columnNumber > queryLines[lineNumber].Length;
                 columnNumber -= (queryLines[lineNumber].Length + 1), ++lineNumber)
            {
                ;
            }

            ++lineNumber; // switch lineNum and colNum to 1-based indexes
            ++columnNumber;

            //
            // Error context format: "[errorContextInfo,] line ddd, column ddd"
            //
            sb = new StringBuilder();
            if (!String.IsNullOrEmpty(errorContextInfo))
            {
                sb.AppendFormat(CultureInfo.CurrentCulture, "{0}, ", errorContextInfo);
            }

            if (errorPosition >= 0)
            {
                sb.AppendFormat(
                    CultureInfo.CurrentCulture,
                    "{0} {1}, {2} {3}",
                    Strings.LocalizedLine,
                    lineNumber,
                    Strings.LocalizedColumn,
                    columnNumber);
            }

            return(sb.ToString());
        }
コード例 #11
0
ファイル: DmlSqlGenerator.cs プロジェクト: jwanagel/jjwtest
        internal static string[] GenerateUpdateSql(DbUpdateCommandTree tree, out List <DbParameter> parameters, bool isLocalProvider)
        {
            var commandTexts = new List <String>();
            var commandText  = new StringBuilder(s_commandTextBuilderInitialCapacity);
            var translator   = new ExpressionTranslator(commandText, tree, null != tree.Returning, isLocalProvider);

            // update [schemaName].[tableName]
            commandText.Append("update ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // set c1 = ..., c2 = ..., ...
            var first = true;

            commandText.Append("set ");
            foreach (DbSetClause setClause in tree.SetClauses)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept(translator);
                commandText.Append(" = ");
                setClause.Value.Accept(translator);
            }

            if (first)
            {
                // If first is still true, it indicates there were no set
                // clauses.
                // - we acquire the appropriate locks
                // - server-gen columns (e.g. timestamp) get recomputed
                //

                // Fix #13533 : A fake update DML updating some column item
                // with the same value as before to acquire the lock on the table
                // while updating some columns in another table. This happens when
                // both the table are dependent on an entity and the members of entity
                // which is mapped to one table is being updated and the other table
                // needs to be locked for consistency.
                string updatableColumnName;
                if (GetUpdatableColumn(tree, out updatableColumnName))
                {
                    commandText.Append("[");
                    commandText.Append(CommonUtils.EscapeSquareBraceNames(updatableColumnName));
                    commandText.Append("] ");
                    commandText.Append(" = ");
                    commandText.Append("[");
                    commandText.Append(CommonUtils.EscapeSquareBraceNames(updatableColumnName));
                    commandText.Append("] ");
                }
                else
                {
                    // Throw some meaningful error
                    throw ADP1.Update(
                              EntityRes.GetString(EntityRes.UpdateStatementCannotBeGeneratedForAcquiringLock),
                              null);
                }
            }
            commandText.AppendLine();

            // where c1 = ..., c2 = ...
            commandText.Append("where ");
            tree.Predicate.Accept(translator);
            commandText.AppendLine();

            commandTexts.Add(commandText.ToString());
            commandText.Length = 0;

            // generate returning sql
            GenerateReturningSql(commandText, tree, translator, tree.Returning);

            if (!String.IsNullOrEmpty(commandText.ToString()))
            {
                commandTexts.Add(commandText.ToString());
            }

            parameters = translator.Parameters;

            return(commandTexts.ToArray());
        }
コード例 #12
0
        internal static void PopulateParameterFromTypeUsage(DbParameter parameter, TypeUsage type)
        {
            Check.NotNull(parameter, "parameter");
            Check.NotNull(type, "type");

            // parameter.Direction - take the default. we don't support output
            // parameters.
            parameter.Direction = ParameterDirection.Input;

            // parameter.IsNullable - from the NullableConstraintAttribute value
            parameter.IsNullable = TypeSemantics.IsNullable(type);

            // parameter.ParameterName - set by the caller;
            // parameter.SourceColumn - not applicable until we have a data adapter;
            // parameter.SourceColumnNullMapping - not applicable until we have a data adapter;
            // parameter.SourceVersion - not applicable until we have a data adapter;
            // parameter.Value - left unset;
            // parameter.DbType - determined by the TypeMapping;
            // parameter.Precision - from the TypeMapping;
            // parameter.Scale - from the TypeMapping;
            // parameter.Size - from the TypeMapping;

            Debug.Assert(null != type, "no type mapping?");

            if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Binary))
            {
                PopulateBinaryParameter(parameter, type, DbType.Binary);
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean))
            {
                parameter.DbType = DbType.Boolean;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Byte))
            {
                parameter.DbType = DbType.Byte;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.DateTime))
            {
                parameter.DbType = DbType.DateTime;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Decimal))
            {
                PopulateDecimalParameter(parameter, type, DbType.Decimal);
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Double))
            {
                parameter.DbType = DbType.Double;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Guid))
            {
                parameter.DbType = DbType.Guid;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Single))
            {
                parameter.DbType = DbType.Single;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Int16))
            {
                parameter.DbType = DbType.Int16;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Int32))
            {
                parameter.DbType = DbType.Int32;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Int64))
            {
                parameter.DbType = DbType.Int64;
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String))
            {
                PopulateStringParameter(parameter, type);
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Time))
            {
                throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "Time"));
            }
            else if (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.DateTimeOffset))
            {
                throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "DateTimeOffset"));
            }
            else
            {
                ADP1.NotSupported(" UnKnown data type");
            }
        }
        // <summary>
        // Determines SqlDbType for the given primitive type. Extracts facet
        // information as well.
        // </summary>
        private static SqlDbType GetSqlDbType(TypeUsage type, out int?size, out byte?precision, out byte?scale)
        {
            // only supported for primitive type
            var primitiveTypeKind = TypeSemantics.GetPrimitiveTypeKind(type);

            size      = default(int?);
            precision = default(byte?);
            scale     = default(byte?);

            // CONSIDER(CMeek):: add logic for Xml here
            switch (primitiveTypeKind)
            {
            case PrimitiveTypeKind.Binary:
                // for output parameters, ensure there is space...
                size = GetParameterSize(type);
                return(GetBinaryDbType(type));

            case PrimitiveTypeKind.Boolean:
                return(SqlDbType.Bit);

            case PrimitiveTypeKind.Byte:
                return(SqlDbType.TinyInt);

            case PrimitiveTypeKind.Time:
                throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "Time"));

            case PrimitiveTypeKind.DateTimeOffset:
                throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "DateTimeOffset"));

            case PrimitiveTypeKind.DateTime:
                return(SqlDbType.DateTime);

            case PrimitiveTypeKind.Decimal:
                precision = GetParameterPrecision(type, null);
                scale     = GetScale(type);
                return(SqlDbType.Decimal);

            case PrimitiveTypeKind.Double:
                return(SqlDbType.Float);

            case PrimitiveTypeKind.Guid:
                return(SqlDbType.UniqueIdentifier);

            case PrimitiveTypeKind.Int16:
                return(SqlDbType.SmallInt);

            case PrimitiveTypeKind.Int32:
                return(SqlDbType.Int);

            case PrimitiveTypeKind.Int64:
                return(SqlDbType.BigInt);

            case PrimitiveTypeKind.SByte:
                return(SqlDbType.SmallInt);

            case PrimitiveTypeKind.Single:
                return(SqlDbType.Real);

            case PrimitiveTypeKind.String:
                size = GetParameterSize(type);
                return(GetStringDbType(type));

            default:
                Debug.Fail("unknown PrimitiveTypeKind " + primitiveTypeKind);
                return(SqlDbType.Variant);
            }
        }
        private DbCommand CreateCommand(DbProviderManifest providerManifest, DbCommandTree commandTree)
        {
            // DEVNOTE/CAUTION: This method could be called either from Remote or Local Provider.
            // Ensure that the code works well with the both provider types.
            // The methods called from the below code also need to be capable
            // of handling both provider types.
            //
            // NOTE: Remote Provider is loaded at runtime, if available.
            // This is done to remove hard dependency on Remote Provider and
            // it might not be present in all scenarios. All Remote Provider
            // type checks need to be done using RemoteProviderHelper class.
            //

            Check.NotNull(providerManifest, "providerManifest");
            Check.NotNull(commandTree, "commandTree");

            if (commandTree is DbFunctionCommandTree)
            {
                throw ADP1.NotSupported(EntityRes.GetString(EntityRes.StoredProceduresNotSupported));
            }

            var command = _isLocalProvider
                              ? new SqlCeMultiCommand()
                              : (DbCommand)RemoteProviderHelper.CreateRemoteProviderType(RemoteProvider.SqlCeCommand);

            command.Connection = null; // don't hold on to the connection when we're going to cache this forever;

            List <DbParameter> parameters;
            CommandType        commandType;

            var commandTexts = SqlGenerator.GenerateSql(commandTree, out parameters, out commandType, _isLocalProvider);

            if (_isLocalProvider)
            {
                Debug.Assert(command is SqlCeMultiCommand, "SqlCeMultiCommand expected");
                // Set the multiple command texts for the command object
                ((SqlCeMultiCommand)command).CommandTexts = commandTexts;
            }
            else
            {
                // Set the command text for the RDP case.
                Debug.Assert(commandTexts.Length == 1, "BatchQueries are not supported in designer scenarios");
                command.CommandText = commandTexts[0];
            }

            command.CommandType = commandType;

            // Now make sure we populate the command's parameters from the CQT's parameters:
            //
            foreach (var queryParameter in commandTree.Parameters)
            {
                DbParameter parameter;
                const bool  ignoreMaxLengthFacet = false;
                parameter = CreateSqlCeParameter(
                    queryParameter.Key, queryParameter.Value, DBNull.Value, ignoreMaxLengthFacet, _isLocalProvider);
                command.Parameters.Add(parameter);
            }

            // Now add parameters added as part of SQL gen (note: this feature is only safe for DML SQL gen which
            // does not support user parameters, where there is no risk of name collision)
            //
            if (null != parameters &&
                0 < parameters.Count)
            {
                if (!(commandTree is DbDeleteCommandTree ||
                      commandTree is DbInsertCommandTree ||
                      commandTree is DbUpdateCommandTree))
                {
                    throw ADP1.InternalError(ADP1.InternalErrorCode.SqlGenParametersNotPermitted);
                }

                foreach (var parameter in parameters)
                {
                    command.Parameters.Add(parameter);
                }
            }

            return(command);
        }
コード例 #15
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static Exception InternalError(InternalErrorCode internalError)
 {
     return(InvalidOperation(EntityRes.GetString(EntityRes.ADP_InternalProviderError, (int)internalError)));
 }
コード例 #16
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static string Update_NotSupportedIdentityType(object p0, object p1)
 {
     return(EntityRes.GetString(EntityRes.Update_NotSupportedIdentityType, new[] { p0, p1 }));
 }
コード例 #17
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 ////////////////////////////////////////////////////////////////////////
 //
 // Provider specific sqlgen errors
 //
 internal static NotSupportedException FullOuterJoinNotSupportedException()
 {
     return(NotSupported(EntityRes.GetString(EntityRes.FullOuterJoinNotSupported)));
 }
コード例 #18
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 ////////////////////////////////////////////////////////////////////////
 //
 // DDl errors
 //
 internal static ArgumentException InvalidConnectionType()
 {
     return(Argument(EntityRes.GetString(EntityRes.InvalidConnectionTypeException)));
 }
コード例 #19
0
ファイル: ADP1.cs プロジェクト: rvegajr/entityframework
 internal static NotSupportedException DMLQueryCannotReturnResultsException()
 {
     return(NotSupported(EntityRes.GetString(EntityRes.DMLQueryCannotReturnResults)));
 }
コード例 #20
0
        // requires: all columns in constraint.ParentColumns and
        // constraint.ChildColumns must have been mapped in some cell in m_cellGroup
        // effects: Given the foreign key constraint, checks if the
        // constraint.ChildColumns are mapped to the constraint.ParentColumns
        // in m_cellGroup in the right oder. If not, adds an error to m_errorLog and returns
        // false. Else returns true
        private bool CheckForeignKeyColumnOrder(Set <Cell> cells, ErrorLog errorLog)
        {
            // Go through every cell and find the cells that are relevant to
            // parent and those that are relevant to child
            // Then for each cell pair (parent, child) make sure that the
            // projected foreign keys columns in C-space are aligned

            List <Cell> parentCells = new List <Cell>();
            List <Cell> childCells  = new List <Cell>();

            foreach (Cell cell in cells)
            {
                if (cell.SQuery.Extent.Equals(ChildTable))
                {
                    childCells.Add(cell);
                }

                if (cell.SQuery.Extent.Equals(ParentTable))
                {
                    parentCells.Add(cell);
                }
            }

            // Make sure that all child cells and parent cells align on
            // the columns, i.e., for each DISTINCT pair C and P, get the columns
            // on the S-side. Then get the corresponding fields on the
            // C-side. The fields on the C-side should match

            bool foundParentCell = false;
            bool foundChildCell  = false;

            foreach (Cell childCell in childCells)
            {
                List <List <int> > allChildSlotNums = GetSlotNumsForColumns(childCell, ChildColumns);

                if (allChildSlotNums.Count == 0)
                { // slots in present in S-side, ignore
                    continue;
                }

                List <MemberPath> childPaths  = null;
                List <MemberPath> parentPaths = null;
                Cell errorParentCell          = null;

                foreach (List <int> childSlotNums in allChildSlotNums)
                {
                    foundChildCell = true;

                    // Get the fields on the C-side
                    childPaths = new List <MemberPath>(childSlotNums.Count);
                    foreach (int childSlotNum in childSlotNums)
                    {
                        // Initial slots only have JoinTreeSlots
                        MemberProjectedSlot childSlot = (MemberProjectedSlot)childCell.CQuery.ProjectedSlotAt(childSlotNum);
                        Debug.Assert(childSlot != null);
                        childPaths.Add(childSlot.MemberPath);
                    }

                    foreach (Cell parentCell in parentCells)
                    {
                        List <List <int> > allParentSlotNums = GetSlotNumsForColumns(parentCell, ParentColumns);
                        if (allParentSlotNums.Count == 0)
                        {
                            // * Parent and child cell are the same - we do not
                            // need to check since we want to check the foreign
                            // key constraint mapping across cells
                            // * Some slots not in present in S-side, ignore
                            continue;
                        }
                        foreach (List <int> parentSlotNums in allParentSlotNums)
                        {
                            foundParentCell = true;

                            parentPaths = new List <MemberPath>(parentSlotNums.Count);
                            foreach (int parentSlotNum in parentSlotNums)
                            {
                                MemberProjectedSlot parentSlot = (MemberProjectedSlot)parentCell.CQuery.ProjectedSlotAt(parentSlotNum);
                                Debug.Assert(parentSlot != null);
                                parentPaths.Add(parentSlot.MemberPath);
                            }

                            // Make sure that the last member of each of these is the same
                            // or the paths are essentially equivalent via referential constraints
                            // We need to check that the last member is essentially the same because it could
                            // be a regular scenario where aid is mapped to PersonAddress and Address - there
                            // is no ref constraint. So when projected into C-Space, we will get Address.aid
                            // and PersonAddress.Address.aid
                            if (childPaths.Count == parentPaths.Count)
                            {
                                bool notAllPathsMatched = false;
                                for (int i = 0; i < childPaths.Count && !notAllPathsMatched; i++)
                                {
                                    MemberPath parentPath = parentPaths[i];
                                    MemberPath childPath  = childPaths[i];

                                    if (!parentPath.LeafEdmMember.Equals(childPath.LeafEdmMember)) //Child path did not match
                                    {
                                        if (parentPath.IsEquivalentViaRefConstraint(childPath))
                                        {
                                            //Specifying the referential constraint once in the C space should be enough.
                                            //This is the only way possible today.
                                            //We might be able to derive more knowledge by using boolean logic
                                            return(true);
                                        }
                                        else
                                        {
                                            notAllPathsMatched = true;
                                        }
                                    }
                                }

                                if (!notAllPathsMatched)
                                {
                                    return(true); //all childPaths matched parentPaths
                                }
                                else
                                {
                                    //If not this one, some other Parent Cell may match.
                                    errorParentCell = parentCell;
                                }
                            }
                        }
                    } //foreach parentCell
                }

                //If execution is at this point, no parent cell's end has matched (otherwise it would have returned true)

                Debug.Assert(childPaths != null, "child paths should be set");
                Debug.Assert(parentPaths != null, "parent paths should be set");
                Debug.Assert(errorParentCell != null, "errorParentCell should be set");
                // using EntityRes. instead of Strings. because the generated method includes 6 instead of 9 parameters
                string message = EntityRes.GetString(EntityRes.ViewGen_Foreign_Key_ColumnOrder_Incorrect,
                                                     ToUserString(),
                                                     MemberPath.PropertiesToUserString(ChildColumns, false),
                                                     ChildTable.Name,
                                                     MemberPath.PropertiesToUserString(childPaths, false),
                                                     childCell.CQuery.Extent.Name,
                                                     MemberPath.PropertiesToUserString(ParentColumns, false),
                                                     ParentTable.Name,
                                                     MemberPath.PropertiesToUserString(parentPaths, false),
                                                     errorParentCell.CQuery.Extent.Name);
                ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ForeignKeyColumnOrderIncorrect, message, new Cell[] { errorParentCell, childCell }, String.Empty);
                errorLog.AddEntry(record);
                return(false);
            }
            Debug.Assert(foundParentCell == true, "Some cell that mapped the parent's key must be present!");
            Debug.Assert(foundChildCell == true, "Some cell that mapped the child's foreign key must be present according to the requires clause!");
            return(true);
        }