/// <summary> /// Deserializes the specified config in a ResultMap object. /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="parameterClass">The parameter class.</param> /// <param name="config">The config.</param> /// <returns></returns> public static ParameterProperty Deserialize( DataExchangeFactory dataExchangeFactory, Type parameterClass, IConfiguration config) { string propertyName = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_PROPERTY); string columnName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_COLUMN); string callBackName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_TYPEHANDLER); string clrType = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_TYPE); string dbType = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_DBTYPE, null); string direction = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_DIRECTION); string nullValue = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_NULLVALUE); Byte precision = ConfigurationUtils.GetByteAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_PRECISION, 0); Byte scale = ConfigurationUtils.GetByteAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SCALE, 0); int size = ConfigurationUtils.GetIntAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SIZE, -1); return new ParameterProperty( propertyName, columnName, callBackName, clrType, dbType, direction, nullValue, precision, scale, size, parameterClass, dataExchangeFactory); }
/// <summary> /// Deserializes the specified config in an ArgumentProperty object /// </summary> /// <param name="config">The config.</param> /// <param name="resultClass">The result class.</param> /// <param name="constructorInfo">The constructor info.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <returns></returns> public static ArgumentProperty Deserialize( IConfiguration config, Type resultClass, ConstructorInfo constructorInfo, DataExchangeFactory dataExchangeFactory) { string argumentName = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_ARGUMENTNAME); string clrType = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_TYPE); string callBackName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_TYPEHANDLER); int columnIndex = ConfigurationUtils.GetIntAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_COLUMNINDEX, ResultProperty.UNKNOWN_COLUMN_INDEX); string columnName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_COLUMN); string dbType = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_DBTYPE); string nestedResultMapName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_RESULTMAPPING); string nullValue = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_NULLVALUE); string select = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SELECT); Type type = GetParameterType(constructorInfo, argumentName); return new ArgumentProperty( argumentName, columnName, columnIndex, clrType, callBackName, dbType, nestedResultMapName, nullValue, select, type, resultClass, dataExchangeFactory, dataExchangeFactory.TypeHandlerFactory.ResolveTypeHandler(type, clrType, dbType) ); }
/// <summary> /// Deserializes a ParameterMap object /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="config">The config.</param> /// <param name="modelStore">The model store.</param> /// <returns></returns> public static ParameterMap Deserialize( DataExchangeFactory dataExchangeFactory, IConfiguration config, IModelStore modelStore) { Type type = null; IDataExchange dataExchange = null; string id = config.Id; string className = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_CLASS); string extendMap = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_EXTENDS); if (className.Length > 0) { type = dataExchangeFactory.TypeHandlerFactory.GetType(className); dataExchange = dataExchangeFactory.GetDataExchangeForClass(type); } else { // Get the ComplexDataExchange dataExchange = dataExchangeFactory.GetDataExchangeForClass(dataExchangeFactory.TypeHandlerFactory.GetTypeAlias(className).Type); } return new ParameterMap( id, className, extendMap, type, dataExchange, modelStore.SessionFactory.DataSource.DbProvider.UsePositionalParameters); }
/// <summary> /// Deserialize the specified config in a ResultProperty object /// </summary> /// <param name="config">The config.</param> /// <param name="resultClass">The result class.</param> /// <param name="prefix">The prefix.</param> /// <param name="suffix">The suffix.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <returns></returns> public static ResultProperty Deserialize( IConfiguration config, Type resultClass, string prefix, string suffix, DataExchangeFactory dataExchangeFactory) { string propertyName = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_PROPERTY); string columnName = prefix+ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_COLUMN)+suffix; int columnIndex = ConfigurationUtils.GetIntAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_COLUMNINDEX, ResultProperty.UNKNOWN_COLUMN_INDEX); string clrType = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_TYPE); string callBackName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_TYPEHANDLER); string dbType = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_DBTYPE); bool isLazyLoad = ConfigurationUtils.GetBooleanAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_LAZYLOAD, false); string nestedResultMapName = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_RESULTMAPPING); string nullValue = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_NULLVALUE); string select = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SELECT); return new ResultProperty( propertyName, columnName, columnIndex, clrType, callBackName, dbType, isLazyLoad, nestedResultMapName, nullValue, select, resultClass, dataExchangeFactory, null ); }
/// <summary> /// Build a Discriminator object /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="resultClass">The result class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="cases">The case element.</param> /// <returns></returns> public static Discriminator Deserialize( IConfiguration configuration, Type resultClass, DataExchangeFactory dataExchangeFactory, IList<Case> cases) { string callBackName = ConfigurationUtils.GetStringAttribute(configuration.Attributes, ConfigConstants.ATTRIBUTE_TYPEHANDLER); string clrType = ConfigurationUtils.GetStringAttribute(configuration.Attributes, ConfigConstants.ATTRIBUTE_TYPE); int columnIndex = ConfigurationUtils.GetIntAttribute(configuration.Attributes, ConfigConstants.ATTRIBUTE_COLUMNINDEX, ResultProperty.UNKNOWN_COLUMN_INDEX); string columnName = ConfigurationUtils.GetStringAttribute(configuration.Attributes, ConfigConstants.ATTRIBUTE_COLUMN); string dbType = ConfigurationUtils.GetStringAttribute(configuration.Attributes, ConfigConstants.ATTRIBUTE_DBTYPE); string nullValue = configuration.GetAttributeValue(ConfigConstants.ATTRIBUTE_NULLVALUE); Discriminator discriminator = new Discriminator( callBackName, clrType, columnIndex, columnName, dbType, nullValue, cases, resultClass, dataExchangeFactory ); return discriminator; }
/// <summary> /// Deserializes the specified config in a CacheModel object. /// </summary> /// <param name="config">The config.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <returns>A CacheModel object</returns> public static CacheModel Deserialize(IConfiguration config, DataExchangeFactory dataExchangeFactory) { string id = config.Id; string type = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_TYPE); type = dataExchangeFactory.TypeHandlerFactory.GetTypeAlias(type).Type.AssemblyQualifiedName; long flushInterval = ConfigurationUtils.GetLongAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_FLUSHINTERVAL, int.MinValue); bool isShare = ConfigurationUtils.GetBooleanAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SHARE, false); int size = ConfigurationUtils.GetIntAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SIZE, int.MinValue); return new CacheModel(id, type, flushInterval, size, isShare); }
public SimpleDynamicSqlTextTokenHandler(DataExchangeFactory dataExchangeFactory, object parameterObject) { if (dataExchangeFactory == null) throw new ArgumentNullException("dataExchangeFactory"); if (parameterObject == null) throw new ArgumentNullException("parameterObject"); _dataExchangeFactory = dataExchangeFactory; _parameterObject = parameterObject; KeepSurroundingToken = false; }
/// <summary> /// Initializes a new instance of the <see cref="StaticSql"/> class. /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="dbHelperParameterCache">The db helper parameter cache.</param> /// <param name="statement">The statement.</param> public StaticSql( DataExchangeFactory dataExchangeFactory, DBHelperParameterCache dbHelperParameterCache, IStatement statement) { Contract.Require.That(dataExchangeFactory, Is.Not.Null).When("retrieving argument dataExchangeFactory in StaticSql constructor"); Contract.Require.That(dbHelperParameterCache, Is.Not.Null).When("retrieving argument dbHelperParameterCache in StaticSql constructor"); Contract.Require.That(statement, Is.Not.Null).When("retrieving argument statement in StaticSql constructor"); this.statement = statement; this.dataExchangeFactory = dataExchangeFactory; this.dbHelperParameterCache = dbHelperParameterCache; }
/// <summary> /// Initializes a new instance of the <see cref="ExternalSql"/> class. /// </summary> /// <param name="modelStore">The model store.</param> /// <param name="statement">The statement.</param> /// <param name="commandText">The command text.</param> public ExternalSql( IModelStore modelStore, IStatement statement, string commandText) { Contract.Require.That(modelStore, Is.Not.Null).When("retrieving argument modelStore in ExternalSql constructor"); Contract.Require.That(statement, Is.Not.Null).When("retrieving argument statement in ExternalSql constructor"); this.statement = statement; this.commandText = commandText; dataExchangeFactory = modelStore.DataExchangeFactory; dbHelperParameterCache = modelStore.DBHelperParameterCache; inlineParemeterMapBuilder = new InlineParemeterMapBuilder(modelStore); }
/// <summary> /// Initializes a new instance of the <see cref="DynamicSql"/> class. /// </summary> /// <param name="usePositionalParameters">if set to <c>true</c> [use positional parameters].</param> /// <param name="dbHelperParameterCache">The db helper parameter cache.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="statement">The statement.</param> public DynamicSql( bool usePositionalParameters, DBHelperParameterCache dbHelperParameterCache, DataExchangeFactory dataExchangeFactory, IStatement statement) { Contract.Require.That(dataExchangeFactory, Is.Not.Null).When("retrieving argument dataExchangeFactory in DynamicSql constructor"); Contract.Require.That(dbHelperParameterCache, Is.Not.Null).When("retrieving argument dbHelperParameterCache in DynamicSql constructor"); Contract.Require.That(statement, Is.Not.Null).When("retrieving argument statement in DynamicSql constructor"); this.statement = statement; this.usePositionalParameters = usePositionalParameters; this.dataExchangeFactory = dataExchangeFactory; this.dbHelperParameterCache = dbHelperParameterCache; paramParser = new InlineParameterMapParser(); }
/// <summary> /// Initializes a new instance of the <see cref="SimpleDynamicSql"/> class. /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="dbHelperParameterCache">The db helper parameter cache.</param> /// <param name="sqlStatement">The SQL statement.</param> /// <param name="statement">The statement.</param> public SimpleDynamicSql( DataExchangeFactory dataExchangeFactory, DBHelperParameterCache dbHelperParameterCache, string sqlStatement, IStatement statement) { Contract.Require.That(dataExchangeFactory, Is.Not.Null).When("retrieving argument dataExchangeFactory in SimpleDynamicSql constructor"); Contract.Require.That(dbHelperParameterCache, Is.Not.Null).When("retrieving argument dbHelperParameterCache in SimpleDynamicSql constructor"); Contract.Require.That(statement, Is.Not.Null).When("retrieving argument statement in SimpleDynamicSql constructor"); Contract.Require.That(sqlStatement, Is.Not.Null & Is.Not.Empty).When("retrieving argument sqlStatement in SimpleDynamicSql constructor"); this.sqlStatement = sqlStatement; this.statement = statement;//sql语句 包含一些参数符号 ? $ this.dataExchangeFactory = dataExchangeFactory; this.dbHelperParameterCache = dbHelperParameterCache; }
/// <summary> /// Deserializes the specified config in a CacheModel object. /// </summary> /// <param name="config">The config.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <returns>A CacheModel object</returns> public static CacheModel Deserialize(IConfiguration config, DataExchangeFactory dataExchangeFactory) { /*<cacheModels>节点信息格式 <cacheModels> <cacheModel id="account-cache" type="Perpetual" flushInterval="30" > <flushOnExecute statement="UpdateAccountViaInlineParameters"/> <flushOnExecute statement="UpdateAccountViaParameterMap"/> </cacheModel> <cacheModels> */ //获取IConfiguration对象中的cacheModel节点属性而已 string id = config.Id; string type = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_TYPE); type = dataExchangeFactory.TypeHandlerFactory.GetTypeAlias(type).Type.AssemblyQualifiedName; long flushInterval = ConfigurationUtils.GetLongAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_FLUSHINTERVAL, int.MinValue); bool isShare = ConfigurationUtils.GetBooleanAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SHARE, false); int size = ConfigurationUtils.GetIntAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SIZE, int.MinValue); return new CacheModel(id, type, flushInterval, size, isShare); }
/// <summary> /// Parse inline parameter with syntax as /// #propertyName,type=string,dbtype=Varchar,direction=Input,nullValue=N/A,handler=string,column=null# /// </summary> /// <param name="token">The token.</param> /// <param name="parameterClassType">Type of the parameter class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="statementId">The statement id.</param> /// <returns></returns> /// <example> /// #propertyName,type=string,dbtype=Varchar,direction=Input,nullValue=N/A,handler=string# /// </example> /// <remarks> /// Updated By: Richard Beacroft /// Updated Date: 11\10\2013 /// Description: Added ability to specify "null" as value for column want to ignore, just for completeness. /// </remarks> /// <example> /// The following will convert [].Equal to the appropriate full reflection name for the Equal field/property on the current iterate element, /// taking into consideration that the iterate element may be within another iterate element, etc... /// @{[].Equal,column=null,type=string,dbtype=Decimal,direction=Input,nullValue=null,handler=null} /// </example> private static ParameterProperty NewParseMapping(string token, Type parameterClassType, DataExchangeFactory dataExchangeFactory, string statementId) { string propertyName = string.Empty; string type = string.Empty; string dbType = string.Empty; string direction = string.Empty; string callBack = string.Empty; string nullValue = null; string columnName = string.Empty; const string NULL_VALUE = "null"; StringTokenizer paramParser = new StringTokenizer(token, "=,", false); IEnumerator enumeratorParam = paramParser.GetEnumerator(); enumeratorParam.MoveNext(); propertyName = ((string)enumeratorParam.Current).Trim(); while (enumeratorParam.MoveNext()) { var field = ((string)enumeratorParam.Current).Trim().ToLower(); if (enumeratorParam.MoveNext()) { var value = ((string)enumeratorParam.Current).Trim(); if ("type".Equals(field)) { if (value == NULL_VALUE) continue; type = value; } else if ("dbtype".Equals(field)) { if (value == NULL_VALUE) continue; dbType = value; } else if ("direction".Equals(field)) { if (value == NULL_VALUE) continue; direction = value; } else if ("nullvalue".Equals(field)) { if (value == NULL_VALUE) continue; if (value.StartsWith("\"") && value.EndsWith("\"")) nullValue = value.Substring(1, value.Length - 2); else nullValue = value; } else if ("handler".Equals(field)) { if (value == NULL_VALUE) continue; callBack = value; } else if ("column".Equals(field)) { if (value == NULL_VALUE) continue; columnName = value; } else { throw new DataMapperException("When parsing inline parameter for statement '" + statementId + "', can't recognize parameter mapping field: '" + field + "' in " + token + ", check your inline parameter syntax."); } } else { throw new DataMapperException("Incorrect inline parameter map format (missmatched name=value pairs): " + token); } } return new ParameterProperty( propertyName, columnName, callBack, type, dbType, direction, nullValue, 0, 0, -1, parameterClassType, dataExchangeFactory); }
/// <summary> /// Parse inline parameter with syntax as /// </summary> /// <param name="token">The token.</param> /// <param name="parameterClassType">Type of the parameter class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <example> /// #propertyName:dbType:nullValue# /// </example> /// <returns></returns> private static ParameterProperty OldParseMapping(string token, Type parameterClassType, DataExchangeFactory dataExchangeFactory) { string propertyName = string.Empty; string dbType = string.Empty; string nullValue = null; if (token.IndexOf(PARAM_DELIM) > -1) { StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true); IEnumerator enumeratorParam = paramParser.GetEnumerator(); int n1 = paramParser.TokenNumber; if (n1 == 3) { enumeratorParam.MoveNext(); propertyName = ((string)enumeratorParam.Current).Trim(); enumeratorParam.MoveNext(); enumeratorParam.MoveNext(); //ignore ":" dbType = ((string)enumeratorParam.Current).Trim(); } else if (n1 >= 5) { enumeratorParam.MoveNext(); propertyName = ((string)enumeratorParam.Current).Trim(); enumeratorParam.MoveNext(); enumeratorParam.MoveNext(); //ignore ":" dbType = ((string)enumeratorParam.Current).Trim(); enumeratorParam.MoveNext(); enumeratorParam.MoveNext(); //ignore ":" nullValue = ((string)enumeratorParam.Current).Trim(); while (enumeratorParam.MoveNext()) { nullValue = nullValue + ((string)enumeratorParam.Current).Trim(); } } else { throw new ConfigurationException("Incorrect inline parameter map format: " + token); } } else { propertyName = token; } return new ParameterProperty( propertyName, string.Empty, string.Empty, string.Empty, dbType, string.Empty, nullValue, 0, 0, -1, parameterClassType, dataExchangeFactory); }
/// <summary> /// Deserializes the specified config. /// </summary> /// <param name="config">The config.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="waitResultPropertyResolution">The wait result property resolution delegate.</param> /// <param name="waitDiscriminatorResolution">The wait discriminator resolution.</param> /// <returns></returns> public static ResultMap Deserialize( IConfiguration config, DataExchangeFactory dataExchangeFactory, WaitResultPropertyResolution waitResultPropertyResolution, WaitDiscriminatorResolution waitDiscriminatorResolution ) { /*resultMaps子节点信息格式 <resultMap id="account-result-constructor" class="Account" > <constructor> <argument argumentName="identifiant" column="Account_ID"/> <argument argumentName="firstName" column="Account_FirstName"/> <argument argumentName="lastName" column="Account_LastName"/> </constructor> <result property="EmailAddress" column="Account_Email" nullValue="*****@*****.**"/> <result property="BannerOption" column="Account_Banner_Option" dbType="Varchar" type="bool"/> <result property="CartOption" column="Account_Cart_Option" typeHandler="HundredsBool"/> </resultMap> */ //从config中对应的resultMap节点获取其属性 string id = config.Id; string className = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_CLASS); string extends = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_EXTENDS); string groupBy = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_GROUPBY); string keyColumns = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_KEYS_PROPERTIES); string suffix = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SUFFIX, string.Empty); string prefix = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_PREFIX, string.Empty); //从工厂类的别名字典中获取 Type type = dataExchangeFactory.TypeHandlerFactory.GetType(className); //根据type类型获取IDataExchange类对象 IDataExchange dataExchange = dataExchangeFactory.GetDataExchangeForClass(type); IFactory factory = null; //准备存储构造函数参数argument节点信息 ArgumentPropertyCollection arguments = new ArgumentPropertyCollection(); #region Get the constructor & associated parameters //获取config下节点构造函数constructor的集合 ConfigurationCollection constructors = config.Children.Find(ConfigConstants.ELEMENT_CONSTRUCTOR); if (constructors.Count > 0) { //默认获取第一个构造函数constructor节点 因为是初始化一个类 一个构造函数就足够了 IConfiguration constructor = constructors[0]; Type[] argumentsType = new Type[constructor.Children.Count]; string[] argumentsName = new string[constructor.Children.Count]; // Builds param name list //argument节点的个数 for (int i = 0; i < constructor.Children.Count; i++) { //argumentName属性的取值 argumentsName[i] = ConfigurationUtils.GetStringAttribute(constructor.Children[i].Attributes, ConfigConstants.ATTRIBUTE_ARGUMENTNAME); } // Find the constructor 匹配构造函数 ConstructorInfo constructorInfo = GetConstructor(id, type, argumentsName); // Build ArgumentProperty and parameter type list //处理构造函数的参数 每一个参数添加到arguments参数列表中 for (int i = 0; i < constructor.Children.Count; i++) { ArgumentProperty argumentMapping = ArgumentPropertyDeSerializer.Deserialize( constructor.Children[i],//第i个Argument节点配置类 type,//当前构造函数的类 constructorInfo,//当前构造函数的信息 dataExchangeFactory); arguments.Add(argumentMapping); //此处NestedResultMapName字符串应该为空 if (argumentMapping.NestedResultMapName.Length > 0) { waitResultPropertyResolution(argumentMapping); } //保存当前参数的类型 argumentsType[i] = argumentMapping.MemberType; } // Init the object factory //构造函数参数信息分析完成 动态初始化这个构造函数 factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, argumentsType); } else { if (!dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type) && type!=typeof(DataRow)) { factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, Type.EmptyTypes); } } #endregion //处理result所有节点 ResultPropertyCollection properties = BuildResultProperties( id, config, type, prefix, suffix, dataExchangeFactory, waitResultPropertyResolution); //对discriminator鉴别器的分析 Discriminator discriminator = BuildDiscriminator(config, type, dataExchangeFactory, waitDiscriminatorResolution); //子节点分析完毕 将这些信息加入到resultMap父节点中 ResultMap resultMap = new ResultMap( id, className, extends, groupBy, keyColumns, type, dataExchange, factory, dataExchangeFactory.TypeHandlerFactory, properties, arguments, discriminator ); return resultMap; }
/// <summary> /// Constructor /// </summary> /// <param name="dataExchangeFactory"></param> protected BaseDataExchange(DataExchangeFactory dataExchangeFactory) { _dataExchangeFactory = dataExchangeFactory; }
/// <summary> /// Initializes a new instance of the <see cref="ArgumentProperty"/> class. /// </summary> /// <param name="argumentName">Name of the argument.</param> /// <param name="columnName">Name of the column.</param> /// <param name="columnIndex">Index of the column.</param> /// <param name="clrType">Type of the CLR.</param> /// <param name="callBackName">Name of the call back.</param> /// <param name="dbType">Type of the db.</param> /// <param name="nestedResultMapName">Name of the nested result map.</param> /// <param name="nullValue">The null value.</param> /// <param name="select">The select.</param> /// <param name="type">The argument type.</param> /// <param name="resultClass">The result class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="typeHandler">The type handler.</param> public ArgumentProperty( string argumentName, string columnName, int columnIndex, string clrType, string callBackName, string dbType, string nestedResultMapName, string nullValue, string select, Type type, Type resultClass, DataExchangeFactory dataExchangeFactory, ITypeHandler typeHandler ) : base("value", columnName, columnIndex, clrType, callBackName, dbType, false, nestedResultMapName, nullValue, select, resultClass, dataExchangeFactory, typeHandler) { Contract.Require.That(argumentName, Is.Not.Null & Is.Not.Empty).When("retrieving argument argumentName in ArgumentProperty constructor"); Contract.Require.That(type, Is.Not.Null & Is.Not.Empty).When("retrieving argument type in ArgumentProperty constructor"); Contract.Require.That(resultClass, Is.Not.Null & Is.Not.Empty).When("retrieving argument resultClass in ArgumentProperty constructor"); this.argumentName = argumentName; this.type = type; argumentStrategy = ArgumentStrategyFactory.Get(this); }
/// <summary> /// Builds the discriminator and his subMaps /// </summary> /// <param name="resultMapConfig">The result map config.</param> /// <param name="resultClass">The result class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="waitDiscriminatorResolution">The wait discriminator resolution.</param> /// <returns></returns> private static Discriminator BuildDiscriminator( IConfiguration resultMapConfig, Type resultClass, DataExchangeFactory dataExchangeFactory, WaitDiscriminatorResolution waitDiscriminatorResolution) { Discriminator discriminator = null; // Build the Discriminator/Case Property //获取resultMap子节点discriminator的集合信息 ConfigurationCollection discriminatorsConfig = resultMapConfig.Children.Find(ConfigConstants.ELEMENT_DISCRIMINATOR); if (discriminatorsConfig.Count > 0) { //configScope.ErrorContext.MoreInfo = "initialize discriminator"; // Find the cases IList<Case> cases = new List<Case>(); //默认获取第一个鉴别器下的子节点case信息集合 ConfigurationCollection caseConfigs = discriminatorsConfig[0].Children.Find(ConfigConstants.ELEMENT_CASE); for (int i = 0; i < caseConfigs.Count; i++) { Case caseElement = CaseDeSerializer.Deserialize(caseConfigs[i]); cases.Add(caseElement); } discriminator = DiscriminatorDeSerializer.Deserialize( discriminatorsConfig[0], resultClass, dataExchangeFactory, cases ); //将discriminator加入到DefaultModelBuilder中的IList<Discriminator> discriminators集合中 waitDiscriminatorResolution(discriminator); } return discriminator; }
/// <summary> /// Cosntructor /// </summary> /// <param name="dataExchangeFactory"></param> public ListDataExchange(DataExchangeFactory dataExchangeFactory):base(dataExchangeFactory) { }
/// <summary> /// Initializes a new instance of the <see cref="ComplexDataExchange"/> class. /// </summary> /// <param name="dataExchangeFactory"></param> public ComplexDataExchange(DataExchangeFactory dataExchangeFactory):base(dataExchangeFactory) { }
/// <summary> /// Constructor /// </summary> /// <param name="callBackName">Name of the call back.</param> /// <param name="clrType">Type of the CLR.</param> /// <param name="columnIndex">Index of the column.</param> /// <param name="columnName">Name of the column.</param> /// <param name="dbType">Type of the db.</param> /// <param name="nullValue">The null value.</param> /// <param name="cases">The cases.</param> /// <param name="resultClass">The result class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> public Discriminator( string callBackName, string clrType, int columnIndex, string columnName, string dbType, string nullValue, IList<Case> cases, Type resultClass, DataExchangeFactory dataExchangeFactory) { Contract.Require.That(columnName, Is.Not.Null & Is.Not.Empty).When("retrieving argument columnName in Discriminator constructor"); this.nullValue = nullValue; this.callBackName = callBackName; this.clrType = clrType; this.columnIndex = columnIndex; this.columnName = columnName; this.dbType = dbType; this.cases = cases; resultMaps = new Dictionary<string, IResultMap>(); mapping = new ResultProperty( "value", columnName, columnIndex, clrType, callBackName, dbType, false, string.Empty, nullValue, string.Empty, resultClass, dataExchangeFactory, null); //mapping.Initialize(configScope, resultClass); }
/// <summary> /// Initializes a new instance of the <see cref="ResultProperty"/> class. /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="columnName">Name of the column.</param> /// <param name="columnIndex">Index of the column.</param> /// <param name="clrType">Type of the CLR.</param> /// <param name="callBackName">Name of the call back.</param> /// <param name="dbType">Type of the db.</param> /// <param name="isLazyLoad">if set to <c>true</c> [is lazy load].</param> /// <param name="nestedResultMapName">Name of the nested result map.</param> /// <param name="nullValue">The null value.</param> /// <param name="select">The select.</param> /// <param name="resultClass">The result class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="typeHandler">The type handler.</param> public ResultProperty( string propertyName, string columnName, int columnIndex, string clrType, string callBackName, string dbType, bool isLazyLoad, string nestedResultMapName, string nullValue, string select, Type resultClass, DataExchangeFactory dataExchangeFactory, ITypeHandler typeHandler ) { Contract.Require.That(propertyName, Is.Not.Null & Is.Not.Empty).When("retrieving argument propertyName in ResultProperty constructor"); this.propertyName = propertyName; this.columnName = columnName; this.callBackName = callBackName; this.dbType = dbType; this.clrType = clrType; this.select = select; this.nestedResultMapName = nestedResultMapName; this.isLazyLoad = isLazyLoad; this.nullValue = nullValue; this.columnIndex = columnIndex; this.typeHandler = typeHandler; #region isComplexMemberName if (propertyName.IndexOf('.') < 0) { isComplexMemberName = false; } else // complex member name FavouriteLineItem.Id { isComplexMemberName = true; } #endregion if ( propertyName.Length>0 && propertyName != "value" && !typeof(IDictionary).IsAssignableFrom(resultClass)&& !typeof(DataRow).IsAssignableFrom(resultClass)) { #region SetAccessor if (!isComplexMemberName) { setAccessor = dataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(resultClass, propertyName); } else // complex member name FavouriteLineItem.Id { MemberInfo propertyInfo = ObjectProbe.GetMemberInfoForSetter(resultClass, propertyName); string memberName = propertyName.Substring(propertyName.LastIndexOf('.') + 1); setAccessor = dataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(propertyInfo.ReflectedType, memberName); } #endregion isGenericIList = TypeUtils.IsImplementGenericIListInterface(MemberType); isIList = typeof(IList).IsAssignableFrom(MemberType); #region Set the list factory if (isGenericIList) { if (MemberType.IsArray) { listFactory = arrayListFactory; } else { Type[] typeArgs = MemberType.GetGenericArguments(); if (typeArgs.Length == 0)// Custom collection which derive from List<T> { listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } else { Type genericIList = typeof(IList<>); Type interfaceListType = genericIList.MakeGenericType(typeArgs); Type genericList = typeof(List<>); Type listType = genericList.MakeGenericType(typeArgs); if ((interfaceListType == MemberType) || (listType == MemberType)) { Type constructedType = genericList.MakeGenericType(typeArgs); listFactory = dataExchangeFactory.ObjectFactory.CreateFactory( constructedType, Type.EmptyTypes); } else // Custom collection which derive from List<T> { listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } } } } else if (isIList) { if (MemberType.IsArray) { listFactory = arrayListFactory; } else { if (MemberType == typeof(IList)) { listFactory = arrayListFactory; } else // custom collection { listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } } } #endregion } #region TypeHandler if (!string.IsNullOrEmpty(CallBackName)) { try { Type type = dataExchangeFactory.TypeHandlerFactory.GetType(CallBackName); ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type); this.typeHandler = new CustomTypeHandler(typeHandlerCallback); } catch (Exception e) { throw new ConfigurationException("Error occurred during custom type handler configuration. Cause: " + e.Message, e); } } else { if (typeHandler == null) { //configScope.ErrorContext.MoreInfo = "Result property '" + propertyName + "' set the typeHandler attribute."; this.typeHandler = dataExchangeFactory.TypeHandlerFactory.ResolveTypeHandler(resultClass, propertyName, clrType, dbType, true); } } #endregion #region LazyLoad if (IsLazyLoad) { lazyFactory = new LazyFactoryBuilder().GetLazyFactory(setAccessor.MemberType); } #endregion if (!GetType().IsSubclassOf(typeof(ResultProperty))) { propertyStrategy = PropertyStrategyFactory.Get(this); } }
/// <summary> /// Initializes a new instance of the <see cref="DictionaryDataExchange"/> class. /// </summary> /// <param name="dataExchangeFactory"></param> public DictionaryDataExchange(DataExchangeFactory dataExchangeFactory):base(dataExchangeFactory) { }
/// <summary> /// Cosntructor /// </summary> /// <param name="dataExchangeFactory"></param> public PrimitiveDataExchange(DataExchangeFactory dataExchangeFactory) : base(dataExchangeFactory) { }
/// <summary> /// Cosntructor /// </summary> /// <param name="dataExchangeFactory"></param> public PrimitiveDataExchange(DataExchangeFactory dataExchangeFactory):base(dataExchangeFactory) { }
/// <summary> /// Parse Inline ParameterMap /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="statementId">The statement id.</param> /// <param name="statement">The statement.</param> /// <param name="sqlStatement">The SQL statement.</param> /// <returns>A new sql command text.</returns> internal static SqlText ParseInlineParameterMap(DataExchangeFactory dataExchangeFactory, string statementId, IStatement statement, string sqlStatement) { string newSql = sqlStatement; List<ParameterProperty> mappingList = new List<ParameterProperty>(); Type parameterClassType = null; if (statement != null) { parameterClassType = statement.ParameterClass; } if (sqlStatement.Contains(NEW_BEGIN_TOKEN)) { // V3 parameter syntax //@{propertyName,column=string,type=string,dbtype=string,direction=[Input/Output/InputOutput],nullValue=string,handler=string} if (newSql != null) { string toAnalyse = newSql; int start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN); int end = toAnalyse.IndexOf(NEW_END_TOKEN); StringBuilder newSqlBuffer = new StringBuilder(); while (start > -1 && end > start) { string prepend = toAnalyse.Substring(0, start); string append = toAnalyse.Substring(end + NEW_END_TOKEN.Length); //EmailAddress,column=string,type=string,dbType=Varchar,[email protected] string parameter = toAnalyse.Substring(start + NEW_BEGIN_TOKEN.Length, end - start - NEW_BEGIN_TOKEN.Length); ParameterProperty mapping = NewParseMapping(parameter, parameterClassType, dataExchangeFactory, statementId); mappingList.Add(mapping); newSqlBuffer.Append(prepend); newSqlBuffer.Append(MARK_TOKEN); toAnalyse = append; start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN); end = toAnalyse.IndexOf(NEW_END_TOKEN); } newSqlBuffer.Append(toAnalyse); newSql = newSqlBuffer.ToString(); } } else { #region old syntax StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true); StringBuilder newSqlBuffer = new StringBuilder(); string token = null; string lastToken = null; IEnumerator enumerator = parser.GetEnumerator(); while (enumerator.MoveNext()) { token = (string)enumerator.Current; if (PARAMETER_TOKEN.Equals(lastToken)) { // Double token ## = # if (PARAMETER_TOKEN.Equals(token)) { newSqlBuffer.Append(PARAMETER_TOKEN); token = null; } else { ParameterProperty mapping = null; if (token.IndexOf(PARAM_DELIM) > -1) { mapping = OldParseMapping(token, parameterClassType, dataExchangeFactory); } else { mapping = NewParseMapping(token, parameterClassType, dataExchangeFactory, statementId); } mappingList.Add(mapping); newSqlBuffer.Append(MARK_TOKEN + " "); enumerator.MoveNext(); token = (string)enumerator.Current; if (!PARAMETER_TOKEN.Equals(token)) { throw new DataMapperException("Unterminated inline parameter in mapped statement (" + statementId + ")."); } token = null; } } else { if (!PARAMETER_TOKEN.Equals(token)) { newSqlBuffer.Append(token); } } lastToken = token; } newSql = newSqlBuffer.ToString(); #endregion old syntax } ParameterProperty[] mappingArray = mappingList.ToArray(); SqlText sqlText = new SqlText(); sqlText.Text = newSql; sqlText.Parameters = mappingArray; return sqlText; }
/// <summary> /// Builds a <see cref="ResultPropertyCollection"/> for an <see cref="AutoResultMap"/>. /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public static ResultPropertyCollection Build(DataExchangeFactory dataExchangeFactory, IDataReader reader, ref object resultObject) { Type targetType = resultObject.GetType(); ResultPropertyCollection properties = new ResultPropertyCollection(); try { // Get all PropertyInfo from the resultObject properties ReflectionInfo reflectionInfo = ReflectionInfo.GetInstance(targetType); string[] membersName = reflectionInfo.GetWriteableMemberNames(); IDictionary<string, ISetAccessor> propertyMap = new Dictionary<string, ISetAccessor>(); int length = membersName.Length; for (int i = 0; i < length; i++) { ISetAccessorFactory setAccessorFactory = dataExchangeFactory.AccessorFactory.SetAccessorFactory; ISetAccessor setAccessor = setAccessorFactory.CreateSetAccessor(targetType, membersName[i]); propertyMap.Add(membersName[i], setAccessor); } // Get all column Name from the reader // and build a resultMap from with the help of the PropertyInfo[]. DataTable dataColumn = reader.GetSchemaTable(); int count = dataColumn.Rows.Count; for (int i = 0; i < count; i++) { string propertyName = string.Empty; string columnName = dataColumn.Rows[i][0].ToString(); ISetAccessor matchedSetAccessor = null; propertyMap.TryGetValue(columnName, out matchedSetAccessor); int columnIndex = i; if (resultObject is Hashtable) { propertyName = columnName; ResultProperty property = new ResultProperty( propertyName, columnName, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, targetType, dataExchangeFactory, null); properties.Add(property); } Type propertyType = null; if (matchedSetAccessor == null) { try { propertyType = ObjectProbe.GetMemberTypeForSetter(resultObject, columnName); } catch { _logger.Error("The column [" + columnName + "] could not be auto mapped to a property on [" + resultObject + "]"); } } else { propertyType = matchedSetAccessor.MemberType; } if (propertyType != null || matchedSetAccessor != null) { propertyName = (matchedSetAccessor != null ? matchedSetAccessor.Name : columnName); ITypeHandler typeHandler = null; if (matchedSetAccessor != null) { //property.Initialize(dataExchangeFactory.TypeHandlerFactory, matchedSetAccessor); typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(matchedSetAccessor.MemberType); } else { typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(propertyType); } //property.PropertyStrategy = PropertyStrategyFactory.Get(property); ResultProperty property = new ResultProperty( propertyName, columnName, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, targetType, dataExchangeFactory, typeHandler); properties.Add(property); } } } catch (Exception e) { throw new DataMapperException("Error automapping columns. Cause: " + e.Message, e); } return properties; }
/// <summary> /// Parse Inline ParameterMap /// 对statement insert update delete select 语句的参数进行分析 /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="statementId">The statement id.</param> /// <param name="statement">The statement.</param> /// <param name="sqlStatement">The SQL statement.</param> /// <returns>A new sql command text.</returns> public static SqlText ParseInlineParameterMap(DataExchangeFactory dataExchangeFactory, string statementId, IStatement statement, string sqlStatement) { string newSql = sqlStatement;//赋值得到一条SQL部分语句 List<ParameterProperty> mappingList = new List<ParameterProperty>(); Type parameterClassType = null; if (statement != null) { parameterClassType = statement.ParameterClass;//当前节点属性中的参数类 会不会有多个参数类的情况??? } if (sqlStatement.Contains(NEW_BEGIN_TOKEN))//如果SQL语句包含"@{" { // V3 parameter syntax //@{propertyName,column=string,type=string,dbype=string,direction=[Input/Output/InputOutput],nullValue=string,handler=string} /*以@{开头的例子 <procedure id="InsertAccountViaSPWithDynamicParameter" parameterClass="Account" > ps_InsertAccountWithDefault @{Id,column=Account_ID}//每一个@对应一个ParameterProperty类 ,@{FirstName,column=Account_FirstName} ,@{LastName,column=Account_LastName} ,@{EmailAddress,column=Account_Email,[email protected]} <isNotNull property="NullBannerOption"> ,@{NullBannerOption,column=Account_Banner_Option,dbType=Varchar,type=bool} </isNotNull> @{CartOption,column=Account_Cart_Option,handler=HundredsBool} </procedure> */ if (newSql != null) { string toAnalyse = newSql; int start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN);//@{的下标 int end = toAnalyse.IndexOf(NEW_END_TOKEN);//"}"的下标 StringBuilder newSqlBuffer = new StringBuilder(); while (start > -1 && end > start) { //将语句以 @{ ****** }拆分成3份字符串 string prepend = toAnalyse.Substring(0, start);//@{部分 string append = toAnalyse.Substring(end + NEW_END_TOKEN.Length);//}.....部分 //EmailAddress,column=string,type=string,dbType=Varchar,[email protected] string parameter = toAnalyse.Substring(start + NEW_BEGIN_TOKEN.Length, end - start - NEW_BEGIN_TOKEN.Length);//第一个中间内容部分 ParameterProperty mapping = NewParseMapping(parameter, parameterClassType, dataExchangeFactory, statementId); mappingList.Add(mapping);//将解析后得到的ParameterProperty放入列表中 newSqlBuffer.Append(prepend);//将”@{"加入 或者是 "},@{"部分加入 newSqlBuffer.Append(MARK_TOKEN);//加入 "?"标志 //可能有多个部分 所以循环处理准备 toAnalyse = append; start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN); end = toAnalyse.IndexOf(NEW_END_TOKEN); } /*while 循环完成后的形势是 * ps_InsertAccountWithDefault * @{?},@{?}的大概格式 保存到newSql中 */ newSqlBuffer.Append(toAnalyse); newSql = newSqlBuffer.ToString(); } } else { #region old syntax /* <insert id="InsertAccountViaInlineParameters" parameterClass="Account" > insert into Accounts (Account_ID, Account_FirstName, Account_LastName, Account_Email) values (#Id#, #FirstName#, #LastName#, #EmailAddress:VarChar:[email protected]#) </insert> */ //每# #之间就是一个ParameterProperty类 StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true);//"#"区分 true表示 如果有#则返回 StringBuilder newSqlBuffer = new StringBuilder(); string token = null; string lastToken = null; IEnumerator enumerator = parser.GetEnumerator(); while (enumerator.MoveNext())//获取当前符号到下一符号之间的字符串 { token = (string)enumerator.Current;//Current真正保存了获取当前符号到下一符号之间的字符串 或 # if (PARAMETER_TOKEN.Equals(lastToken)) //如果上一次是# { // Double token ## = # //先处理# if (PARAMETER_TOKEN.Equals(token)) //如果当前也是# { newSqlBuffer.Append(PARAMETER_TOKEN); token = null; } else //如果当前不是# 也即是两个#之间的字符串 { ParameterProperty mapping = null; //判断# #之间的内容是否含有“:” if (token.IndexOf(PARAM_DELIM) > -1) //如果字符串中含有”:"符号 则进入该函数 { mapping = OldParseMapping(token, parameterClassType, dataExchangeFactory); } else //不含有":",则再次默认","为分隔符 { mapping = NewParseMapping(token, parameterClassType, dataExchangeFactory, statementId); } mappingList.Add(mapping); newSqlBuffer.Append(MARK_TOKEN + " ");//添加"?"作为标志符号 enumerator.MoveNext(); token = (string)enumerator.Current; if (!PARAMETER_TOKEN.Equals(token)) { throw new DataMapperException("Unterminated inline parameter in mapped statement (" + statementId + ")."); } token = null; } } else { if (!PARAMETER_TOKEN.Equals(token)) { newSqlBuffer.Append(token); } } lastToken = token; } /*处理后的sql语句格式应该为 insert into Accounts (Account_ID, Account_FirstName, Account_LastName, Account_Email) values (?, ?, ?, ?) *?对应的参数保存在 mappingList中 *将这两部分 放到SqlText类中 */ newSql = newSqlBuffer.ToString(); #endregion } //将List内容转化为数组的形式 ParameterProperty[] mappingArray = mappingList.ToArray(); //将处理后的简化SQL语句 和 参数列表 保存到 SqlText中 SqlText sqlText = new SqlText(); sqlText.Text = newSql; sqlText.Parameters = mappingArray; return sqlText; }
/// <summary> /// Builds the result properties. /// </summary> /// <param name="resultMapId">The result map id.</param> /// <param name="resultMapConfig">The result map config.</param> /// <param name="resultClass">The result class.</param> /// <param name="prefix">The prefix.</param> /// <param name="suffix">The suffix.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="waitResultPropertyResolution">The wait result property resolution.</param> /// <returns></returns> private static ResultPropertyCollection BuildResultProperties( string resultMapId, IConfiguration resultMapConfig, Type resultClass, string prefix, string suffix, DataExchangeFactory dataExchangeFactory, WaitResultPropertyResolution waitResultPropertyResolution) { ResultPropertyCollection properties = new ResultPropertyCollection(); //获取result节点的集合配置信息 ConfigurationCollection resultsConfig = resultMapConfig.Children.Find(ConfigConstants.ELEMENT_RESULT); for (int i = 0; i < resultsConfig.Count; i++) { ResultProperty mapping = null; try { mapping = ResultPropertyDeSerializer.Deserialize(resultsConfig[i], resultClass, prefix, suffix, dataExchangeFactory); } catch(Exception e) { throw new ConfigurationException("In ResultMap (" + resultMapId + ") can't build the result property: " + ConfigurationUtils.GetStringAttribute(resultsConfig[i].Attributes, ConfigConstants.ATTRIBUTE_PROPERTY) + ". Cause " + e.Message, e); } if (mapping.NestedResultMapName.Length > 0)//resultMapping属性如果有值 此处一般会有 { //添加到DefaultModelBuilder中的ResultPropertyCollection nestedProperties集合中 waitResultPropertyResolution(mapping); } properties.Add(mapping); } return properties; }
/// <summary> /// Initializes a new instance of the <see cref="ParameterProperty"/> class. /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="columnName">Name of the column.</param> /// <param name="callBackName">Name of the call back.</param> /// <param name="clrType">Type of the CLR.</param> /// <param name="dbType">Type of the db.</param> /// <param name="directionAttribute">The direction attribute.</param> /// <param name="nullValue">The null value.</param> /// <param name="precision">The precision.</param> /// <param name="scale">The scale.</param> /// <param name="size">The size.</param> /// <param name="parameterClass">The parameter class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> public ParameterProperty( string propertyName, string columnName, string callBackName, string clrType, string dbType, string directionAttribute, string nullValue, Byte precision, Byte scale, int size, Type parameterClass, DataExchangeFactory dataExchangeFactory ) { Contract.Require.That(propertyName, Is.Not.Null & Is.Not.Empty).When("retrieving argument propertyName in ParameterProperty constructor"); this.columnName = columnName; this.callBackName = callBackName; this.clrType = clrType; this.dbType = dbType; this.nullValue = nullValue; this.precision = precision; this.scale = scale; this.size = size; #region Direction if (directionAttribute.Length > 0) { direction = (ParameterDirection)Enum.Parse(typeof(ParameterDirection), directionAttribute, true); this.directionAttribute = direction.ToString(); } #endregion #region Property Name this.propertyName = propertyName; if (propertyName.IndexOf('.') < 0) { isComplexMemberName = false; } else // complex member name FavouriteLineItem.Id { isComplexMemberName = true; } #endregion #region GetAccessor if (!typeof(IDictionary).IsAssignableFrom(parameterClass) // Hashtable parameter map && parameterClass != null // value property && !dataExchangeFactory.TypeHandlerFactory.IsSimpleType(parameterClass)) // value property { if (!isComplexMemberName) { IGetAccessorFactory getAccessorFactory = dataExchangeFactory.AccessorFactory.GetAccessorFactory; getAccessor = getAccessorFactory.CreateGetAccessor(parameterClass, propertyName); } else // complex member name FavouriteLineItem.Id { string memberName = propertyName.Substring(propertyName.LastIndexOf('.') + 1); string parentName = propertyName.Substring(0, propertyName.LastIndexOf('.')); Type parentType = ObjectProbe.GetMemberTypeForGetter(parameterClass, parentName); IGetAccessorFactory getAccessorFactory = dataExchangeFactory.AccessorFactory.GetAccessorFactory; getAccessor = getAccessorFactory.CreateGetAccessor(parentType, memberName); } } #endregion #region TypeHandler if (CallBackName.Length > 0) { try { Type type = dataExchangeFactory.TypeHandlerFactory.GetType(CallBackName); ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type); typeHandler = new CustomTypeHandler(typeHandlerCallback); } catch (Exception e) { throw new ConfigurationException("Error occurred during custom type handler configuration. Cause: " + e.Message, e); } } else { if (CLRType.Length == 0) // Unknown { if (getAccessor != null && dataExchangeFactory.TypeHandlerFactory.IsSimpleType(getAccessor.MemberType)) { // Primitive typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(getAccessor.MemberType, dbType); } else { typeHandler = dataExchangeFactory.TypeHandlerFactory.GetUnkownTypeHandler(); } } else // If we specify a CLR type, use it { Type type = TypeUtils.ResolveType(CLRType); if (dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type)) { // Primitive typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType); } else { // .NET object type = ObjectProbe.GetMemberTypeForGetter(parameterClass, PropertyName); typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType); } } } #endregion }
/// <summary> /// Deserializes the specified config. /// </summary> /// <param name="config">The config.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="waitResultPropertyResolution">The wait result property resolution delegate.</param> /// <param name="waitDiscriminatorResolution">The wait discriminator resolution.</param> /// <returns></returns> public static ResultMap Deserialize( IConfiguration config, DataExchangeFactory dataExchangeFactory, WaitResultPropertyResolution waitResultPropertyResolution, WaitDiscriminatorResolution waitDiscriminatorResolution ) { string id = config.Id; string className = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_CLASS); string extends = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_EXTENDS); string groupBy = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_GROUPBY); string keyColumns = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_KEYS_PROPERTIES); string suffix = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SUFFIX, string.Empty); string prefix = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_PREFIX, string.Empty); Type type = dataExchangeFactory.TypeHandlerFactory.GetType(className); IDataExchange dataExchange = dataExchangeFactory.GetDataExchangeForClass(type); IFactory factory = null; ArgumentPropertyCollection arguments = new ArgumentPropertyCollection(); #region Get the constructor & associated parameters ConfigurationCollection constructors = config.Children.Find(ConfigConstants.ELEMENT_CONSTRUCTOR); if (constructors.Count > 0) { IConfiguration constructor = constructors[0]; Type[] argumentsType = new Type[constructor.Children.Count]; string[] argumentsName = new string[constructor.Children.Count]; // Builds param name list for (int i = 0; i < constructor.Children.Count; i++) { argumentsName[i] = ConfigurationUtils.GetStringAttribute(constructor.Children[i].Attributes, ConfigConstants.ATTRIBUTE_ARGUMENTNAME); } // Find the constructor ConstructorInfo constructorInfo = GetConstructor(id, type, argumentsName); // Build ArgumentProperty and parameter type list for (int i = 0; i < constructor.Children.Count; i++) { ArgumentProperty argumentMapping = ArgumentPropertyDeSerializer.Deserialize( constructor.Children[i], type, constructorInfo, dataExchangeFactory); arguments.Add(argumentMapping); if (argumentMapping.NestedResultMapName.Length > 0) { waitResultPropertyResolution(argumentMapping); } argumentsType[i] = argumentMapping.MemberType; } // Init the object factory factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, argumentsType); } else { if (!dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type) && type!=typeof(DataRow)) { factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, Type.EmptyTypes); } } #endregion ResultPropertyCollection properties = BuildResultProperties( id, config, type, prefix, suffix, dataExchangeFactory, waitResultPropertyResolution); Discriminator discriminator = BuildDiscriminator(config, type, dataExchangeFactory, waitDiscriminatorResolution); ResultMap resultMap = new ResultMap( id, className, extends, groupBy, keyColumns, type, dataExchange, factory, dataExchangeFactory.TypeHandlerFactory, properties, arguments, discriminator ); return resultMap; }