FunctionUpdateCommand.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / FunctionUpdateCommand.cs / 1 / FunctionUpdateCommand.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Data.Common.CommandTrees; 
using System.Data.Metadata.Edm;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common.CommandTrees.Internal; 
using System.Data.Common.Utils;
using System.Diagnostics; 
using System.Data.Common; 
using System.Data.Objects;
using System.Data.EntityClient; 
using System.Globalization;
using System.Data.Entity;
using System.Linq;
namespace System.Data.Mapping.Update.Internal 
{
    ///  
    /// Aggregates information about a modification command delegated to a store function. 
    /// 
    internal sealed class FunctionUpdateCommand : UpdateCommand 
    {
        #region Constructors
        /// 
        /// Initialize a new function command. Initializes the command object. 
        /// 
        /// Function mapping metadata 
        /// Translator 
        /// Primary state entry for this function (additional
        /// state entries can be added later, for instance for relationship navigation bindings) 
        internal FunctionUpdateCommand(StorageFunctionMapping functionMapping, UpdateTranslator translator,
            IEntityStateEntry stateEntry)
        {
            EntityUtil.CheckArgumentNull(functionMapping, "functionMapping"); 
            EntityUtil.CheckArgumentNull(translator, "translator");
            EntityUtil.CheckArgumentNull(stateEntry, "stateEntry"); 
 
            // populate the main state entry for error reporting
            m_stateEntries = new List(1); 
            m_stateEntries.Add(stateEntry);

            // create a command
            DbCommandDefinition commandDefinition = translator.GenerateCommandDefinition(functionMapping); 
            m_dbCommand = commandDefinition.CreateCommand();
        } 
        #endregion 

        #region Fields 
        private readonly List m_stateEntries;

        /// 
        /// Gets the store command wrapped by this command. 
        /// 
        private readonly DbCommand m_dbCommand; 
 
        /// 
        /// Gets pairs for column names and propagator results (so that we can associate reader results with 
        /// the source records for server generated values).
        /// 
        private List> m_resultColumns;
 
        /// 
        /// Gets map from identifiers (key component proxies) to parameters holding the actual 
        /// key values. Supports propagation of identifier values (fixup for server-gen keys) 
        /// 
        private List> m_inputIdentifiers; 

        /// 
        /// Gets map from identifiers (key component proxies) to column names producing the actual
        /// key values. Supports propagation of identifier values (fixup for server-gen keys) 
        /// 
        private Dictionary m_outputIdentifiers; 
 
        /// 
        /// Gets a reference to the rows affected output parameter for the stored procedure. May be null. 
        /// 
        private DbParameter m_rowsAffectedParameter;
        #endregion
 
        #region Properties
        internal override IEnumerable InputIdentifiers 
        { 
            get
            { 
                if (null == m_inputIdentifiers)
                {
                    yield break;
                } 
                else
                { 
                    foreach (KeyValuePair inputIdentifier in m_inputIdentifiers) 
                    {
                        yield return inputIdentifier.Key; 
                    }
                }
            }
        } 

        internal override IEnumerable OutputIdentifiers 
        { 
            get
            { 
                if (null == m_outputIdentifiers)
                {
                    return Enumerable.Empty();
                } 
                return m_outputIdentifiers.Keys;
            } 
        } 

        internal override UpdateCommandKind Kind 
        {
            get { return UpdateCommandKind.Function; }
        }
        #endregion 

        #region Methods 
        ///  
        /// Gets state entries contributing to this function. Supports error reporting.
        ///  
        internal override List GetStateEntries(UpdateTranslator translator)
        {
            return m_stateEntries;
        } 

        // Adds and register a DbParameter to the current command. 
        internal void SetParameterValue(PropagatorResult result, StorageFunctionParameterBinding parameterBinding, UpdateTranslator translator) 
        {
            // retrieve DbParameter 
            DbParameter parameter = this.m_dbCommand.Parameters[parameterBinding.Parameter.Name];
            parameter.Value = translator.KeyManager.GetPrincipalValue(result);

            // if the parameter corresponds to an identifier (key component), remember this fact in case 
            // it's important for dependency ordering (e.g., output the identifier before creating it)
            long identifier = result.Identifier; 
            if (PropagatorResult.NullIdentifier != identifier) 
            {
                const int initialSize = 2; // expect on average less than two input identifiers per command 
                if (null == m_inputIdentifiers)
                {
                    m_inputIdentifiers = new List>(initialSize);
                } 
                foreach (long principal in translator.KeyManager.GetPrincipals(identifier))
                { 
                    m_inputIdentifiers.Add(new KeyValuePair(principal, parameter)); 
                }
 
                // if there is a dependent state entry, remember that this command also handles the entry
                foreach (IEntityStateEntry stateEntry in translator.KeyManager.GetDependentStateEntries(identifier))
                {
                    m_stateEntries.Add(stateEntry); 
                }
            } 
        } 

        // Adds and registers a DbParameter taking the number of rows affected 
        internal void RegisterRowsAffectedParameter(FunctionParameter rowsAffectedParameter)
        {
            if (null != rowsAffectedParameter)
            { 
                Debug.Assert(MetadataHelper.GetPrimitiveTypeKind(rowsAffectedParameter.TypeUsage) ==
                    PrimitiveTypeKind.Int32, "when loading mapping metadata, we check that the parameter is Int32"); 
                Debug.Assert(rowsAffectedParameter.Mode == ParameterMode.Out, 
                    "when loading mapping metadata, we check that the parameter is an out parameter");
                m_rowsAffectedParameter = m_dbCommand.Parameters[rowsAffectedParameter.Name]; 
            }
        }

        // Registers a new state entry as part of the context for this command (for error reporting). 
        internal void RegisterStateEntry(IEntityStateEntry stateEntry)
        { 
            m_stateEntries.Add(EntityUtil.CheckArgumentNull(stateEntry, "stateEntry")); 
        }
 
        // Adds a result column binding from a column name (from the result set for the function) to
        // a propagator result (which contains the context necessary to back-propagate the result).
        // If the result is an identifier, binds the
        internal void AddResultColumn(UpdateTranslator translator, String columnName, PropagatorResult result) 
        {
            const int initializeSize = 2; // expect on average less than two result columns per command 
            if (null == m_resultColumns) 
            {
                m_resultColumns = new List>(initializeSize); 
            }
            m_resultColumns.Add(new KeyValuePair(columnName, result));

            long identifier = result.Identifier; 
            if (PropagatorResult.NullIdentifier != identifier)
            { 
                if (translator.KeyManager.HasPrincipals(identifier)) 
                {
                    throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Update_GeneratedDependent(columnName)); 
                }

                // register output identifier to enable fix-up and dependency tracking
                AddOutputIdentifier(columnName, identifier); 
            }
        } 
 
        // Indicate that a column in the command result set (specified by 'columnName') produces the
        // value for a key component (specified by 'identifier') 
        private void AddOutputIdentifier(String columnName, Int64 identifier)
        {
            const int initialSize = 2; // expect on average less than two identifier output per command
            if (null == m_outputIdentifiers) 
            {
                m_outputIdentifiers = new Dictionary(initialSize); 
            } 
            m_outputIdentifiers[identifier] = columnName;
        } 

        // efects: Executes the current function command in the given transaction and connection context.
        // All server-generated values are added to the generatedValues list. If those values are identifiers, they are
        // also added to the identifierValues dictionary, which associates proxy identifiers for keys in the session 
        // with their actual values, permitting fix-up of identifiers across relationships.
        internal override int Execute(UpdateTranslator translator, EntityConnection connection, Dictionary identifierValues, 
            List> generatedValues) 
        {
            // configure command to use the connection and transaction for this session 
            m_dbCommand.Transaction = ((null != connection.CurrentTransaction) ? connection.CurrentTransaction.StoreTransaction : null);
            m_dbCommand.Connection = connection.StoreConnection;
            if (translator.CommandTimeout.HasValue)
            { 
                m_dbCommand.CommandTimeout = translator.CommandTimeout.Value;
            } 
 
            // set all identifier inputs (to support propagation of identifier values across relationship
            // boundaries) 
            if (null != m_inputIdentifiers)
            {
                foreach (KeyValuePair inputIdentifier in m_inputIdentifiers)
                { 
                    object value;
                    if (identifierValues.TryGetValue(inputIdentifier.Key, out value)) 
                    { 
                        // set the actual value for the identifier if it has been produced by some
                        // other command 
                        inputIdentifier.Value.Value = value;
                    }
                }
            } 

            // Execute the query 
            int rowsAffected; 
            if (null != m_resultColumns)
            { 
                // If there are result columns, read the server gen results
                rowsAffected = 0;
                using (DbDataReader reader = m_dbCommand.ExecuteReader(CommandBehavior.SequentialAccess))
                { 
                    // Retrieve only the first row from the first result set
                    if (reader.Read()) 
                    { 
                        rowsAffected++;
 
                        foreach (var resultColumn in m_resultColumns
                            .Select(r => new KeyValuePair(GetColumnOrdinal(translator, reader, r.Key), r.Value))
                            .OrderBy(r => r.Key)) // order by column ordinal to avoid breaking SequentialAccess readers
                        { 
                            int columnOrdinal = resultColumn.Key;
                            object value = reader.GetValue(columnOrdinal); 
 
                            // register for back-propagation
                            PropagatorResult result = resultColumn.Value; 
                            generatedValues.Add(new KeyValuePair(result, value));

                            // register identifier if it exists
                            Int64 identifier = result.Identifier; 
                            if (PropagatorResult.NullIdentifier != identifier)
                            { 
                                identifierValues.Add(identifier, value); 
                            }
                        } 
                    }

                    // Consume the current reader (and subsequent result sets) so that any errors
                    // executing the function can be intercepted 
                    CommandHelper.ConsumeReader(reader);
                } 
            } 
            else
            { 
                rowsAffected = m_dbCommand.ExecuteNonQuery();
            }

            // if an explicit rows affected parameter exists, use this value instead 
            if (null != m_rowsAffectedParameter)
            { 
                // by design, negative row counts indicate failure iff. an explicit rows 
                // affected parameter is used
                if (DBNull.Value.Equals(m_rowsAffectedParameter.Value)) 
                {
                    rowsAffected = 0;
                }
                else 
                {
                    try 
                    { 
                        rowsAffected = Convert.ToInt32(m_rowsAffectedParameter.Value, CultureInfo.InvariantCulture);
                    } 
                    catch (Exception e)
                    {
                        if (UpdateTranslator.RequiresContext(e))
                        { 
                            // wrap the exception
                            throw EntityUtil.Update(System.Data.Entity.Strings.Update_UnableToConvertRowsAffectedParameterToInt32( 
                                m_rowsAffectedParameter.ParameterName, typeof(int).FullName), e, this.GetStateEntries(translator)); 
                        }
                        throw; 
                    }
                }
            }
 
            return rowsAffected;
        } 
 
        private int GetColumnOrdinal(UpdateTranslator translator, DbDataReader reader, string columnName)
        { 
            int columnOrdinal;
            try
            {
                columnOrdinal = reader.GetOrdinal(columnName); 
            }
            catch (IndexOutOfRangeException) 
            { 
                throw EntityUtil.Update(System.Data.Entity.Strings.Update_MissingResultColumn(columnName), null,
                    this.GetStateEntries(translator)); 
            }
            return columnOrdinal;
        }
 
        internal override int CompareToType(UpdateCommand otherCommand)
        { 
            Debug.Assert(!object.ReferenceEquals(this, otherCommand), "caller should ensure other command is different"); 

            FunctionUpdateCommand other = (FunctionUpdateCommand)otherCommand; 

            // first state entry is the 'main' state entry for the command (see ctor)
            IEntityStateEntry thisParent = this.m_stateEntries[0];
            IEntityStateEntry otherParent = other.m_stateEntries[0]; 

            // order by state 
            int result = (int)thisParent.State - (int)otherParent.State; 
            if (0 != result) { return result; }
 
            // order by entity set
            result = StringComparer.Ordinal.Compare(thisParent.EntitySet.Name, otherParent.EntitySet.Name);
            if (0 != result) { return result; }
            result = StringComparer.Ordinal.Compare(thisParent.EntitySet.EntityContainer.Name, otherParent.EntitySet.EntityContainer.Name); 
            if (0 != result) { return result; }
 
            // order by key values 
            int thisInputIdentifierCount = (null == this.m_inputIdentifiers ? 0 : this.m_inputIdentifiers.Count);
            int otherInputIdentifierCount = (null == other.m_inputIdentifiers ? 0 : other.m_inputIdentifiers.Count); 
            result = thisInputIdentifierCount - otherInputIdentifierCount;
            if (0 != result) { return result; }
            for (int i = 0; i < thisInputIdentifierCount; i++)
            { 
                DbParameter thisParameter = this.m_inputIdentifiers[i].Value;
                DbParameter otherParameter = other.m_inputIdentifiers[i].Value; 
                result = Comparer.Default.Compare(thisParameter.Value, otherParameter.Value); 
                if (0 != result) { return result; }
            } 

            return result;
        }
 
        #endregion
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Data.Common.CommandTrees; 
using System.Data.Metadata.Edm;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common.CommandTrees.Internal; 
using System.Data.Common.Utils;
using System.Diagnostics; 
using System.Data.Common; 
using System.Data.Objects;
using System.Data.EntityClient; 
using System.Globalization;
using System.Data.Entity;
using System.Linq;
namespace System.Data.Mapping.Update.Internal 
{
    ///  
    /// Aggregates information about a modification command delegated to a store function. 
    /// 
    internal sealed class FunctionUpdateCommand : UpdateCommand 
    {
        #region Constructors
        /// 
        /// Initialize a new function command. Initializes the command object. 
        /// 
        /// Function mapping metadata 
        /// Translator 
        /// Primary state entry for this function (additional
        /// state entries can be added later, for instance for relationship navigation bindings) 
        internal FunctionUpdateCommand(StorageFunctionMapping functionMapping, UpdateTranslator translator,
            IEntityStateEntry stateEntry)
        {
            EntityUtil.CheckArgumentNull(functionMapping, "functionMapping"); 
            EntityUtil.CheckArgumentNull(translator, "translator");
            EntityUtil.CheckArgumentNull(stateEntry, "stateEntry"); 
 
            // populate the main state entry for error reporting
            m_stateEntries = new List(1); 
            m_stateEntries.Add(stateEntry);

            // create a command
            DbCommandDefinition commandDefinition = translator.GenerateCommandDefinition(functionMapping); 
            m_dbCommand = commandDefinition.CreateCommand();
        } 
        #endregion 

        #region Fields 
        private readonly List m_stateEntries;

        /// 
        /// Gets the store command wrapped by this command. 
        /// 
        private readonly DbCommand m_dbCommand; 
 
        /// 
        /// Gets pairs for column names and propagator results (so that we can associate reader results with 
        /// the source records for server generated values).
        /// 
        private List> m_resultColumns;
 
        /// 
        /// Gets map from identifiers (key component proxies) to parameters holding the actual 
        /// key values. Supports propagation of identifier values (fixup for server-gen keys) 
        /// 
        private List> m_inputIdentifiers; 

        /// 
        /// Gets map from identifiers (key component proxies) to column names producing the actual
        /// key values. Supports propagation of identifier values (fixup for server-gen keys) 
        /// 
        private Dictionary m_outputIdentifiers; 
 
        /// 
        /// Gets a reference to the rows affected output parameter for the stored procedure. May be null. 
        /// 
        private DbParameter m_rowsAffectedParameter;
        #endregion
 
        #region Properties
        internal override IEnumerable InputIdentifiers 
        { 
            get
            { 
                if (null == m_inputIdentifiers)
                {
                    yield break;
                } 
                else
                { 
                    foreach (KeyValuePair inputIdentifier in m_inputIdentifiers) 
                    {
                        yield return inputIdentifier.Key; 
                    }
                }
            }
        } 

        internal override IEnumerable OutputIdentifiers 
        { 
            get
            { 
                if (null == m_outputIdentifiers)
                {
                    return Enumerable.Empty();
                } 
                return m_outputIdentifiers.Keys;
            } 
        } 

        internal override UpdateCommandKind Kind 
        {
            get { return UpdateCommandKind.Function; }
        }
        #endregion 

        #region Methods 
        ///  
        /// Gets state entries contributing to this function. Supports error reporting.
        ///  
        internal override List GetStateEntries(UpdateTranslator translator)
        {
            return m_stateEntries;
        } 

        // Adds and register a DbParameter to the current command. 
        internal void SetParameterValue(PropagatorResult result, StorageFunctionParameterBinding parameterBinding, UpdateTranslator translator) 
        {
            // retrieve DbParameter 
            DbParameter parameter = this.m_dbCommand.Parameters[parameterBinding.Parameter.Name];
            parameter.Value = translator.KeyManager.GetPrincipalValue(result);

            // if the parameter corresponds to an identifier (key component), remember this fact in case 
            // it's important for dependency ordering (e.g., output the identifier before creating it)
            long identifier = result.Identifier; 
            if (PropagatorResult.NullIdentifier != identifier) 
            {
                const int initialSize = 2; // expect on average less than two input identifiers per command 
                if (null == m_inputIdentifiers)
                {
                    m_inputIdentifiers = new List>(initialSize);
                } 
                foreach (long principal in translator.KeyManager.GetPrincipals(identifier))
                { 
                    m_inputIdentifiers.Add(new KeyValuePair(principal, parameter)); 
                }
 
                // if there is a dependent state entry, remember that this command also handles the entry
                foreach (IEntityStateEntry stateEntry in translator.KeyManager.GetDependentStateEntries(identifier))
                {
                    m_stateEntries.Add(stateEntry); 
                }
            } 
        } 

        // Adds and registers a DbParameter taking the number of rows affected 
        internal void RegisterRowsAffectedParameter(FunctionParameter rowsAffectedParameter)
        {
            if (null != rowsAffectedParameter)
            { 
                Debug.Assert(MetadataHelper.GetPrimitiveTypeKind(rowsAffectedParameter.TypeUsage) ==
                    PrimitiveTypeKind.Int32, "when loading mapping metadata, we check that the parameter is Int32"); 
                Debug.Assert(rowsAffectedParameter.Mode == ParameterMode.Out, 
                    "when loading mapping metadata, we check that the parameter is an out parameter");
                m_rowsAffectedParameter = m_dbCommand.Parameters[rowsAffectedParameter.Name]; 
            }
        }

        // Registers a new state entry as part of the context for this command (for error reporting). 
        internal void RegisterStateEntry(IEntityStateEntry stateEntry)
        { 
            m_stateEntries.Add(EntityUtil.CheckArgumentNull(stateEntry, "stateEntry")); 
        }
 
        // Adds a result column binding from a column name (from the result set for the function) to
        // a propagator result (which contains the context necessary to back-propagate the result).
        // If the result is an identifier, binds the
        internal void AddResultColumn(UpdateTranslator translator, String columnName, PropagatorResult result) 
        {
            const int initializeSize = 2; // expect on average less than two result columns per command 
            if (null == m_resultColumns) 
            {
                m_resultColumns = new List>(initializeSize); 
            }
            m_resultColumns.Add(new KeyValuePair(columnName, result));

            long identifier = result.Identifier; 
            if (PropagatorResult.NullIdentifier != identifier)
            { 
                if (translator.KeyManager.HasPrincipals(identifier)) 
                {
                    throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Update_GeneratedDependent(columnName)); 
                }

                // register output identifier to enable fix-up and dependency tracking
                AddOutputIdentifier(columnName, identifier); 
            }
        } 
 
        // Indicate that a column in the command result set (specified by 'columnName') produces the
        // value for a key component (specified by 'identifier') 
        private void AddOutputIdentifier(String columnName, Int64 identifier)
        {
            const int initialSize = 2; // expect on average less than two identifier output per command
            if (null == m_outputIdentifiers) 
            {
                m_outputIdentifiers = new Dictionary(initialSize); 
            } 
            m_outputIdentifiers[identifier] = columnName;
        } 

        // efects: Executes the current function command in the given transaction and connection context.
        // All server-generated values are added to the generatedValues list. If those values are identifiers, they are
        // also added to the identifierValues dictionary, which associates proxy identifiers for keys in the session 
        // with their actual values, permitting fix-up of identifiers across relationships.
        internal override int Execute(UpdateTranslator translator, EntityConnection connection, Dictionary identifierValues, 
            List> generatedValues) 
        {
            // configure command to use the connection and transaction for this session 
            m_dbCommand.Transaction = ((null != connection.CurrentTransaction) ? connection.CurrentTransaction.StoreTransaction : null);
            m_dbCommand.Connection = connection.StoreConnection;
            if (translator.CommandTimeout.HasValue)
            { 
                m_dbCommand.CommandTimeout = translator.CommandTimeout.Value;
            } 
 
            // set all identifier inputs (to support propagation of identifier values across relationship
            // boundaries) 
            if (null != m_inputIdentifiers)
            {
                foreach (KeyValuePair inputIdentifier in m_inputIdentifiers)
                { 
                    object value;
                    if (identifierValues.TryGetValue(inputIdentifier.Key, out value)) 
                    { 
                        // set the actual value for the identifier if it has been produced by some
                        // other command 
                        inputIdentifier.Value.Value = value;
                    }
                }
            } 

            // Execute the query 
            int rowsAffected; 
            if (null != m_resultColumns)
            { 
                // If there are result columns, read the server gen results
                rowsAffected = 0;
                using (DbDataReader reader = m_dbCommand.ExecuteReader(CommandBehavior.SequentialAccess))
                { 
                    // Retrieve only the first row from the first result set
                    if (reader.Read()) 
                    { 
                        rowsAffected++;
 
                        foreach (var resultColumn in m_resultColumns
                            .Select(r => new KeyValuePair(GetColumnOrdinal(translator, reader, r.Key), r.Value))
                            .OrderBy(r => r.Key)) // order by column ordinal to avoid breaking SequentialAccess readers
                        { 
                            int columnOrdinal = resultColumn.Key;
                            object value = reader.GetValue(columnOrdinal); 
 
                            // register for back-propagation
                            PropagatorResult result = resultColumn.Value; 
                            generatedValues.Add(new KeyValuePair(result, value));

                            // register identifier if it exists
                            Int64 identifier = result.Identifier; 
                            if (PropagatorResult.NullIdentifier != identifier)
                            { 
                                identifierValues.Add(identifier, value); 
                            }
                        } 
                    }

                    // Consume the current reader (and subsequent result sets) so that any errors
                    // executing the function can be intercepted 
                    CommandHelper.ConsumeReader(reader);
                } 
            } 
            else
            { 
                rowsAffected = m_dbCommand.ExecuteNonQuery();
            }

            // if an explicit rows affected parameter exists, use this value instead 
            if (null != m_rowsAffectedParameter)
            { 
                // by design, negative row counts indicate failure iff. an explicit rows 
                // affected parameter is used
                if (DBNull.Value.Equals(m_rowsAffectedParameter.Value)) 
                {
                    rowsAffected = 0;
                }
                else 
                {
                    try 
                    { 
                        rowsAffected = Convert.ToInt32(m_rowsAffectedParameter.Value, CultureInfo.InvariantCulture);
                    } 
                    catch (Exception e)
                    {
                        if (UpdateTranslator.RequiresContext(e))
                        { 
                            // wrap the exception
                            throw EntityUtil.Update(System.Data.Entity.Strings.Update_UnableToConvertRowsAffectedParameterToInt32( 
                                m_rowsAffectedParameter.ParameterName, typeof(int).FullName), e, this.GetStateEntries(translator)); 
                        }
                        throw; 
                    }
                }
            }
 
            return rowsAffected;
        } 
 
        private int GetColumnOrdinal(UpdateTranslator translator, DbDataReader reader, string columnName)
        { 
            int columnOrdinal;
            try
            {
                columnOrdinal = reader.GetOrdinal(columnName); 
            }
            catch (IndexOutOfRangeException) 
            { 
                throw EntityUtil.Update(System.Data.Entity.Strings.Update_MissingResultColumn(columnName), null,
                    this.GetStateEntries(translator)); 
            }
            return columnOrdinal;
        }
 
        internal override int CompareToType(UpdateCommand otherCommand)
        { 
            Debug.Assert(!object.ReferenceEquals(this, otherCommand), "caller should ensure other command is different"); 

            FunctionUpdateCommand other = (FunctionUpdateCommand)otherCommand; 

            // first state entry is the 'main' state entry for the command (see ctor)
            IEntityStateEntry thisParent = this.m_stateEntries[0];
            IEntityStateEntry otherParent = other.m_stateEntries[0]; 

            // order by state 
            int result = (int)thisParent.State - (int)otherParent.State; 
            if (0 != result) { return result; }
 
            // order by entity set
            result = StringComparer.Ordinal.Compare(thisParent.EntitySet.Name, otherParent.EntitySet.Name);
            if (0 != result) { return result; }
            result = StringComparer.Ordinal.Compare(thisParent.EntitySet.EntityContainer.Name, otherParent.EntitySet.EntityContainer.Name); 
            if (0 != result) { return result; }
 
            // order by key values 
            int thisInputIdentifierCount = (null == this.m_inputIdentifiers ? 0 : this.m_inputIdentifiers.Count);
            int otherInputIdentifierCount = (null == other.m_inputIdentifiers ? 0 : other.m_inputIdentifiers.Count); 
            result = thisInputIdentifierCount - otherInputIdentifierCount;
            if (0 != result) { return result; }
            for (int i = 0; i < thisInputIdentifierCount; i++)
            { 
                DbParameter thisParameter = this.m_inputIdentifiers[i].Value;
                DbParameter otherParameter = other.m_inputIdentifiers[i].Value; 
                result = Comparer.Default.Compare(thisParameter.Value, otherParameter.Value); 
                if (0 != result) { return result; }
            } 

            return result;
        }
 
        #endregion
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK