Пример #1
0
		protected override void BuildAbstractMethod()
		{
			// Any class variable must be initialized before use
			// as the same instance of the class is utilized to build abstract methods.
			//
			_paramList           = new ArrayList();
			_refParamList        = new ArrayList();
			_formatParamList     = new ArrayList();
			_mapOutputParameters = new ArrayList();
			_destination         = null;
			_createManager       = true;
			_objectType          = null;
			_explicitObjectType  = false;
			_parameters          = Context.CurrentMethod.GetParameters();
			_locManager          = Context.MethodBuilder.Emitter.DeclareLocal(typeof(DbManager));
			_locObjType          = Context.MethodBuilder.Emitter.DeclareLocal(typeof(Type));
			_outputParameters    = null;
			_sqlQueryAttribute   = null;

			GetSqlQueryAttribute();
			ProcessParameters();

			Type returnType = MethodReturnType;
			ReturnType rt = GetReturnType(returnType);

			CreateDbManager(rt != ReturnType.Enumerable);
			SetObjectType();

			// Define execution method type.
			//
			switch (rt)
			{
				case ReturnType.DataReader : ExecuteReader();            break;
				case ReturnType.DataSet    : ExecuteDataSet(returnType); break;
				case ReturnType.DataTable  : ExecuteDataTable();         break;
				case ReturnType.Void       : ExecuteNonQuery();          break;
				case ReturnType.Scalar     : ExecuteScalar();            break;
				case ReturnType.Enumerable : ExecuteEnumerable();        break;

				case ReturnType.List:

					if (!_explicitObjectType)
					{
						Type elementType = TypeHelper.GetListItemType(returnType);

						if (elementType == typeof(object) && _destination != null)
							elementType = TypeHelper.GetListItemType(Context.CurrentMethod.ReturnType);

						if (elementType != typeof(object))
							_objectType = elementType;

						if (ActualTypes.ContainsKey(_objectType))
							_objectType = ActualTypes[_objectType];
					}

					if (_objectType == null || _objectType == typeof(object))
						ThrowTypeBuilderException(Resources.DataAccessorBuilder_BadListItemType);

					if (TypeHelper.IsScalar(_objectType))
						ExecuteScalarList();
					else
						ExecuteList();

					break;

				case ReturnType.Dictionary:
					{
						Type elementType = null;
						Type keyType = typeof(object);
						Type[] gTypes = TypeHelper.GetGenericArguments(returnType, typeof(IDictionary));

						if ((gTypes == null || gTypes.Length != 2) && _destination != null)
							gTypes = TypeHelper.GetGenericArguments(_destination.ParameterType, typeof(IDictionary));

						if (gTypes != null && gTypes.Length == 2)
						{
							keyType = gTypes[0];
							elementType = gTypes[1];
						}

						if (elementType == null || _explicitObjectType)
							elementType = _objectType;

						if (elementType == null || elementType == typeof(object))
							ThrowTypeBuilderException(Resources.DataAccessorBuilder_BadListItemType);

						bool isIndex = TypeHelper.IsSameOrParent(typeof(CompoundValue), keyType);

						if (keyType != typeof(object) && !isIndex && !TypeHelper.IsScalar(keyType))
							ThrowTypeBuilderException(
								Resources.DataAccessorBuilder_BadKeyType);

						MethodInfo mi = Context.CurrentMethod;

						object[] attrs = mi.GetCustomAttributes(typeof(IndexAttribute), true);
						NameOrIndexParameter[] fields = new NameOrIndexParameter[0];

						if (attrs.Length != 0)
							fields = ((IndexAttribute)attrs[0]).Fields;

						if (fields.Length > 1 && keyType != typeof(object) && !isIndex)
							ThrowTypeBuilderException(
								Resources.DataAccessor_InvalidKeyType);

						if (TypeHelper.IsScalar(elementType))
						{
							attrs = mi.GetCustomAttributes(typeof(ScalarFieldNameAttribute), true);

							if (attrs.Length == 0)
								ThrowTypeBuilderException(Resources.DataAccessorBuilder_ScalarFieldNameMissing);

							NameOrIndexParameter scalarField = ((ScalarFieldNameAttribute)attrs[0]).NameOrIndex;

							if (fields.Length == 0)
								ExecuteScalarDictionaryWithPK(keyType, scalarField, elementType);
							else if (isIndex || fields.Length > 1)
								ExecuteScalarDictionaryWithMapIndex(fields, scalarField, elementType);
							else
								ExecuteScalarDictionaryWithScalarKey(fields[0], keyType, scalarField, elementType);
						}
						else
						{
							if (!_explicitObjectType && ActualTypes.ContainsKey(elementType))
								elementType = ActualTypes[elementType];

							if (fields.Length == 0)
								ExecuteDictionaryWithPK(keyType, elementType);
							else if (isIndex || fields.Length > 1)
								ExecuteDictionaryWithMapIndex(fields, elementType);
							else
								ExecuteDictionaryWithScalarKey(fields[0], elementType);
						}
					}

					break;

				default:

					if (_objectType == null)
						_objectType = returnType;

					if (!_explicitObjectType && ActualTypes.ContainsKey(_objectType))
						_objectType = ActualTypes[_objectType];

					ExecuteObject();

					break;
			}

			GetOutRefParameters();

			if (rt != ReturnType.Enumerable)
				Finally();
		}
Пример #2
0
		void GetSqlQueryAttribute()
		{
			object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(SqlQueryAttribute), true);

			if (attrs.Length != 0)
				_sqlQueryAttribute = (SqlQueryAttribute)attrs[0];
		}
Пример #3
0
		protected override void BuildAbstractMethod()
		{
			// Any class variable must be initialized before use
			// as the same instance of the class is utilized to build abstract methods.
			//
			_paramList           = new ArrayList();
			_refParamList        = new ArrayList();
			_formatParamList     = new ArrayList();
			_mapOutputParameters = new ArrayList();
			_destination         = null;
			_createManager       = true;
			_objectType          = null;
			_explicitObjectType  = false;
			_parameters          = Context.CurrentMethod.GetParameters();
			_locManager          = Context.MethodBuilder.Emitter.DeclareLocal(typeof(DbManager));
			_locObjType          = Context.MethodBuilder.Emitter.DeclareLocal(typeof(Type));
			_outputParameters    = null;
			_sqlQueryAttribute   = null;

			GetSqlQueryAttribute();
			ProcessParameters();
			CreateDbManager();
			SetObjectType();

			// Define execute method type.
			//
			Type returnType = _destination != null? _destination.ParameterType: Context.CurrentMethod.ReturnType;

			if (returnType == typeof(IDataReader))
			{
				ExecuteReader();
			}
			else if (returnType == typeof(DataSet) || returnType.IsSubclassOf(typeof(DataSet)))
			{
				ExecuteDataSet(returnType);
			}
			else if (returnType == typeof(DataTable) || returnType.IsSubclassOf(typeof(DataTable)))
			{
				ExecuteDataTable();
			}
			else if (!returnType.IsArray && (IsInterfaceOf(returnType, typeof(IList))
				|| returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IList<>)))
			{
				if (!_explicitObjectType)
				{
					Type elementType = TypeHelper.GetListItemType(returnType);

					if (elementType == typeof(object) && _destination != null)
						elementType = TypeHelper.GetListItemType(Context.CurrentMethod.ReturnType);

					if (elementType != typeof(object))
						_objectType = elementType;

					if (ActualTypes.ContainsKey(_objectType))
						_objectType = ActualTypes[_objectType];
				}

				if (_objectType == null || _objectType == typeof(object))
					throw new TypeBuilderException(string.Format(
						"Can not determine object type for method '{0}.{1}'",
						Context.CurrentMethod.DeclaringType.Name,
						Context.CurrentMethod.Name));

				if (TypeHelper.IsScalar(_objectType))
					ExecuteScalarList();
				else
					ExecuteList();
			}
			else if (IsInterfaceOf(returnType, typeof(IDictionary))
				|| returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
			{
				Type   elementType = null;
				Type   keyType     = typeof(object);
				Type[] gTypes      = TypeHelper.GetGenericArguments(returnType, typeof(IDictionary));

				if ((gTypes == null || gTypes.Length != 2) && _destination != null)
					gTypes = TypeHelper.GetGenericArguments(_destination.ParameterType, typeof(IDictionary));

				if (gTypes != null && gTypes.Length == 2)
				{
					keyType     = gTypes[0];
					elementType = gTypes[1];
				}

				if (elementType == null || _explicitObjectType)
					elementType = _objectType;

				if (elementType == null || elementType == typeof(object))
					throw new TypeBuilderException(string.Format(
						"Can not determine object type for the method '{0}.{1}'",
						Context.CurrentMethod.DeclaringType.Name,
						Context.CurrentMethod.Name));

				bool isIndex = TypeHelper.IsSameOrParent(typeof(CompoundValue), keyType);

				if (keyType != typeof(object) && !isIndex && !TypeHelper.IsScalar(keyType))
					throw new TypeBuilderException(string.Format(
						"Key type for the method '{0}.{1}' can be of type object, CompoundValue, or a scalar type.",
						Context.CurrentMethod.DeclaringType.Name,
						Context.CurrentMethod.Name));

				MethodInfo mi = Context.CurrentMethod;

				object[] attrs = mi.GetCustomAttributes(typeof(IndexAttribute), true);
				NameOrIndexParameter[] fields = new NameOrIndexParameter[0];

				if (attrs.Length != 0)
					fields = ((IndexAttribute)attrs[0]).Fields;

				if (fields.Length > 1 && keyType != typeof(object) && !isIndex)
					throw new TypeBuilderException(string.Format(
						"Key type for the method '{0}.{1}' can be of type object or CompoundValue.",
						Context.CurrentMethod.DeclaringType.Name,
						Context.CurrentMethod.Name));

				if (TypeHelper.IsScalar(elementType))
				{
					attrs = mi.GetCustomAttributes(typeof(ScalarFieldNameAttribute), true);

					if (attrs.Length == 0)
						throw new TypeBuilderException(string.Format(
							"Scalar field name is not defined for the method '{0}.{1}'.",
							Context.CurrentMethod.DeclaringType.Name,
							Context.CurrentMethod.Name));

					NameOrIndexParameter scalarField = ((ScalarFieldNameAttribute)attrs[0]).NameOrIndex;

					if (fields.Length == 0)
						ExecuteScalarDictionaryWithPK(keyType, scalarField, elementType);
					else if (isIndex || fields.Length > 1)
						ExecuteScalarDictionaryWithMapIndex(fields, scalarField, elementType);
					else
						ExecuteScalarDictionaryWithScalarKey(fields[0], keyType, scalarField, elementType);
				}
				else
				{
					if (!_explicitObjectType && ActualTypes.ContainsKey(elementType))
						elementType = ActualTypes[elementType];

					if (fields.Length == 0)
						ExecuteDictionaryWithPK(keyType, elementType);
					else if (isIndex || fields.Length > 1)
						ExecuteDictionaryWithMapIndex(fields, elementType);
					else
						ExecuteDictionaryWithScalarKey(fields[0], elementType);
				}
			}
			else if (returnType == typeof(void))
			{
				ExecuteNonQuery();
			}
			else if (TypeHelper.IsScalar(returnType.IsByRef? returnType.GetElementType(): returnType))
			{
				ExecuteScalar();
			}
			else
			{
				if (_objectType == null)
					_objectType = returnType;

				if (!_explicitObjectType && ActualTypes.ContainsKey(_objectType))
					_objectType = ActualTypes[_objectType];

				ExecuteObject();
			}

			GetOutRefParameters();
			Finally();
		}