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(); }
void GetSqlQueryAttribute() { object[] attrs = Context.CurrentMethod.GetCustomAttributes(typeof(SqlQueryAttribute), true); if (attrs.Length != 0) _sqlQueryAttribute = (SqlQueryAttribute)attrs[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(); }