You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			200 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //---------------------------------------------------------------------
 | |
| // <copyright file="CommandHelper.cs" company="Microsoft">
 | |
| //      Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| //
 | |
| // @owner Microsoft
 | |
| // @backupOwner Microsoft
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| namespace System.Data.Common.Utils
 | |
| {
 | |
|     using System.Data.EntityClient;
 | |
|     using System.Data.Metadata.Edm;
 | |
|     using System.Data.Spatial;
 | |
|     using System.Diagnostics;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Contains utility methods for construction of DB commands through generic
 | |
|     /// provider interfaces.
 | |
|     /// </summary>
 | |
|     internal static class CommandHelper
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Consumes all rows and result sets from the reader. This allows client to retrieve
 | |
|         /// parameter values and intercept any store exceptions.
 | |
|         /// </summary>
 | |
|         /// <param name="reader">reader to consume</param>
 | |
|         internal static void ConsumeReader(DbDataReader reader)
 | |
|         {
 | |
|             if (null != reader && !reader.IsClosed)
 | |
|             {
 | |
|                 while (reader.NextResult())
 | |
|                 {
 | |
|                     // Note that we only walk through the result sets. We don't need
 | |
|                     // to walk through individual rows (though underlying provider
 | |
|                     // implementation may do so)
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// requires: commandText must not be null
 | |
|         /// The command text must be in the form Container.FunctionImportName.
 | |
|         /// </summary>
 | |
|         internal static void ParseFunctionImportCommandText(string commandText, string defaultContainerName, out string containerName, out string functionImportName)
 | |
|         {
 | |
|             Debug.Assert(null != commandText);
 | |
| 
 | |
|             // Split the string
 | |
|             string[] nameParts = commandText.Split('.');
 | |
|             containerName = null;
 | |
|             functionImportName = null;
 | |
|             if (2 == nameParts.Length)
 | |
|             {
 | |
|                 containerName = nameParts[0].Trim();
 | |
|                 functionImportName = nameParts[1].Trim();
 | |
|             }
 | |
|             else if (1 == nameParts.Length && null != defaultContainerName)
 | |
|             {
 | |
|                 containerName = defaultContainerName;
 | |
|                 functionImportName = nameParts[0].Trim();
 | |
|             }
 | |
|             if (string.IsNullOrEmpty(containerName) || string.IsNullOrEmpty(functionImportName))
 | |
|             {
 | |
|                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_InvalidStoredProcedureCommandText);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Given an entity command, returns the associated entity transaction and performs validation
 | |
|         /// to ensure the transaction is consistent.
 | |
|         /// </summary>
 | |
|         /// <param name="entityCommand">Entity command instance. Must not be null.</param>
 | |
|         /// <returns>Entity transaction</returns>
 | |
|         internal static EntityTransaction GetEntityTransaction(EntityCommand entityCommand)
 | |
|         {
 | |
|             Debug.Assert(null != entityCommand);
 | |
|             EntityTransaction entityTransaction = (EntityTransaction)entityCommand.Transaction;
 | |
| 
 | |
|             // Check to make sure that either the command has no transaction associated with it, or it
 | |
|             // matches the one used by the connection
 | |
|             if (entityTransaction != null && entityTransaction != entityCommand.Connection.CurrentTransaction)
 | |
|             {
 | |
|                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_InvalidTransactionForCommand);
 | |
|             }
 | |
|             // Now we have asserted that EntityCommand either has no transaction or has one that matches the
 | |
|             // one used in the connection, we can simply use the connection's transaction object
 | |
|             entityTransaction = entityCommand.Connection.CurrentTransaction;
 | |
|             return entityTransaction;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Given an entity command and entity transaction, passes through relevant state to store provider
 | |
|         /// command.
 | |
|         /// </summary>
 | |
|         /// <param name="entityCommand">Entity command. Must not be null.</param>
 | |
|         /// <param name="entityTransaction">Entity transaction. Must not be null.</param>
 | |
|         /// <param name="storeProviderCommand">Store provider command that is being setup. Must not be null.</param>
 | |
|         internal static void SetStoreProviderCommandState(EntityCommand entityCommand, EntityTransaction entityTransaction, DbCommand storeProviderCommand)
 | |
|         {
 | |
|             Debug.Assert(null != entityCommand);
 | |
|             Debug.Assert(null != storeProviderCommand);
 | |
| 
 | |
|             storeProviderCommand.CommandTimeout = entityCommand.CommandTimeout;
 | |
|             storeProviderCommand.Connection = ((EntityConnection)entityCommand.Connection).StoreConnection;
 | |
|             storeProviderCommand.Transaction = (null != entityTransaction) ? entityTransaction.StoreTransaction : null;
 | |
|             storeProviderCommand.UpdatedRowSource = entityCommand.UpdatedRowSource;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Given an entity command, store provider command and a connection, sets all output parameter values on the entity command.
 | |
|         /// The connection is used to determine how to map spatial values.
 | |
|         /// </summary>
 | |
|         /// <param name="entityCommand">Entity command on which to set parameter values. Must not be null.</param>
 | |
|         /// <param name="storeProviderCommand">Store provider command from which to retrieve parameter values. Must not
 | |
|         /// be null.</param>
 | |
|         /// <param name="connection">The connection on which the command was run.  Must not be null</param>
 | |
|         internal static void SetEntityParameterValues(EntityCommand entityCommand, DbCommand storeProviderCommand, EntityConnection connection)
 | |
|         {
 | |
|             Debug.Assert(null != entityCommand);
 | |
|             Debug.Assert(null != storeProviderCommand);
 | |
|             Debug.Assert(null != connection);
 | |
| 
 | |
|             foreach (DbParameter storeParameter in storeProviderCommand.Parameters)
 | |
|             {
 | |
|                 ParameterDirection direction = storeParameter.Direction;
 | |
|                 if (0 != (direction & ParameterDirection.Output))
 | |
|                 {
 | |
|                     // if the entity command also defines the parameter, propagate store parameter value
 | |
|                     // to entity parameter
 | |
|                     int parameterOrdinal = entityCommand.Parameters.IndexOf(storeParameter.ParameterName);
 | |
|                     if (0 <= parameterOrdinal)
 | |
|                     {
 | |
|                         EntityParameter entityParameter = entityCommand.Parameters[parameterOrdinal];
 | |
|                         object parameterValue = storeParameter.Value;
 | |
|                         TypeUsage parameterType = entityParameter.GetTypeUsage();
 | |
|                         if (Helper.IsSpatialType(parameterType))
 | |
|                         {
 | |
|                             parameterValue = GetSpatialValueFromProviderValue(parameterValue, (PrimitiveType)parameterType.EdmType, connection);
 | |
|                         }
 | |
|                         entityParameter.Value = parameterValue;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private static object GetSpatialValueFromProviderValue(object spatialValue, PrimitiveType parameterType, EntityConnection connection)
 | |
|         {
 | |
|             DbProviderServices providerServices = DbProviderServices.GetProviderServices(connection.StoreConnection);
 | |
|             StoreItemCollection storeItemCollection = (StoreItemCollection)connection.GetMetadataWorkspace().GetItemCollection(DataSpace.SSpace);
 | |
|             DbSpatialServices spatialServices = providerServices.GetSpatialServices(storeItemCollection.StoreProviderManifestToken);
 | |
|             if (Helper.IsGeographicType(parameterType))
 | |
|             {
 | |
|                 return spatialServices.GeographyFromProviderValue(spatialValue);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Debug.Assert(Helper.IsGeometricType(parameterType));
 | |
|                 return spatialServices.GeometryFromProviderValue(spatialValue);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // requires: all arguments must be given
 | |
|         internal static EdmFunction FindFunctionImport(MetadataWorkspace workspace, string containerName, string functionImportName)
 | |
|         {
 | |
|             Debug.Assert(null != workspace && null != containerName && null != functionImportName);
 | |
|             // find entity container
 | |
|             EntityContainer entityContainer;
 | |
|             if (!workspace.TryGetEntityContainer(containerName, DataSpace.CSpace, out entityContainer))
 | |
|             {
 | |
|                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_UnableToFindFunctionImportContainer(
 | |
|                     containerName));
 | |
|             }
 | |
| 
 | |
|             // find function import
 | |
|             EdmFunction functionImport = null;
 | |
|             foreach (EdmFunction candidate in entityContainer.FunctionImports)
 | |
|             {
 | |
|                 if (candidate.Name == functionImportName)
 | |
|                 {
 | |
|                     functionImport = candidate;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|             if (null == functionImport)
 | |
|             {
 | |
|                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_UnableToFindFunctionImport(
 | |
|                     containerName, functionImportName));
 | |
|             }
 | |
|             if (functionImport.IsComposableAttribute)
 | |
|             {
 | |
|                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_FunctionImportMustBeNonComposable(containerName + "." + functionImportName));
 | |
|             }
 | |
|             return functionImport;
 | |
|         }
 | |
|     }
 | |
| }
 |