public StructuredParameterSchema(ISerializationTypeInfo typeInfo, ISerializationTypeMappingProvider typeMappingProvider) { SetupColumns(typeInfo.Type.Name, typeInfo.Type.Namespace); DataColumn columnName = Columns[SchemaTableColumn.ColumnName]; DataColumn allowDbNull = Columns[SchemaTableColumn.AllowDBNull]; DataColumn dataType = Columns[SchemaTableColumn.DataType]; /* DataColumn numericScale = Columns[SchemaTableColumn.NumericScale]; DataColumn numericPrecision = Columns[SchemaTableColumn.NumericPrecision]; DataColumn columnSize = Columns[SchemaTableColumn.ColumnSize]; */ DataColumn baseColumnName = Columns[SchemaTableColumn.BaseColumnName]; DataColumn providerType = Columns[SchemaTableColumn.ProviderType]; DataColumn nonVersionedProviderType = Columns[SchemaTableColumn.NonVersionedProviderType]; DataColumn columnOrdinal = Columns[SchemaTableColumn.ColumnOrdinal]; List<SqlColumnInfo> sqlColumnInfos = new List<SqlColumnInfo>(); List<ColumnInfo> columns = new List<ColumnInfo>(); Dictionary<SqlColumnInfo, int> columnIndices = new Dictionary<SqlColumnInfo, int>(); if (typeInfo.Mapping.IsNativeType) { DataRow row = NewRow(); row[columnName] = "value"; row[columnOrdinal] = 0; row[dataType] = typeInfo.Type; row[allowDbNull] = true; row[baseColumnName] = "value"; row[providerType] = (int)typeInfo.Mapping.DbType; Rows.Add(row); columns.Add(new ColumnInfo(0, "value", Enum.GetName(typeof(SqlDbType), typeInfo.Mapping.DbType), typeInfo.Type)); IMemberConverter memberConverter = MemberConverter.Get(typeInfo.Type, false, "value", 0, DateTimeKind.Unspecified); sqlColumnInfos.Add(new SqlColumnInfo(typeMappingProvider.GetMapping(typeInfo.Type), "value", memberConverter)); } else { foreach (MemberInfo memberInfo in typeInfo.Type.GetAllFieldsAndProperties()) { SqlColumnAttribute sqlColumn = SqlColumnAttributeBase.Get<SqlColumnAttribute>(memberInfo, false); if (sqlColumn != null) { Type memberType = memberInfo.GetMemberType(); SqlColumnInfo sqlColumnInfo = typeInfo.Mapping.Columns[sqlColumn.Name]; StructuredParameterAttribute parameterAttribute = StructuredParameterAttribute.GetStructuredParameterAttribute(memberInfo); Debug.Assert(parameterAttribute != null); ColumnInfo ci = new ColumnInfo(sqlColumnInfos.Count, sqlColumnInfo.Name, GetDataTypeName(sqlColumnInfo, memberType), memberType); DataRow row = NewRow(); row[columnName] = ci.ColumnName; row[columnOrdinal] = parameterAttribute.Position; row[dataType] = Nullable.GetUnderlyingType(ci.DataType) ?? ci.DataType; row[allowDbNull] = ci.DataType.IsNullableType(); row[baseColumnName] = ci.ColumnName; row[providerType] = (int)sqlColumnInfo.DbType; row[nonVersionedProviderType] = (int)sqlColumnInfo.DbType; Rows.Add(row); columnIndices.Add(sqlColumnInfo, parameterAttribute.Position); sqlColumnInfos.Add(sqlColumnInfo); columns.Add(ci); } } sqlColumnInfos = sqlColumnInfos.OrderBy(ci => columnIndices[ci]).ToList(); } MappedColumns = sqlColumnInfos.AsReadOnly(); ColumnsInfos = columns.ToArray(); if ((MappedColumns.Count != 1) ||(MappedColumns[0].MemberInfo != null)) { ExtractMembers = MembersMethods.Get(MappedColumns.Select(c => c.MemberInfo).ToArray()).ExtractMembers; } AcceptChanges(); }
public SqlCallParameterInfo(ISerializationTypeInfoProvider serializationTypeInfoProvider, ParameterInfo param, ProcedureName procedureName, ProcedureParameter script, ISerializationTypeMappingProvider typeMappingProvider) : base(procedureName, script, GetParameterDirection(param), GetParameterNullable(param), GetParameterEnumerable(param)) { parameterInfo = param; if (SqlType == SqlDbType.Structured) { Type structuredType; if (!param.ParameterType.TryGetIEnumerableElementType(out structuredType)) { throw new ArgumentException("The given parameter must implement IEnumerable<> in order to be used as SQL structured parameter"); } CreateTypeAsTableStatement createTableTypeScript; if (!AssemblyInventory.Get(param.Member.DeclaringType.Assembly).TryFind(script.ParameterTypeName.Name.Value, out createTableTypeScript)) { throw new ArgumentException(string.Format("The given structured parameter table type {0} cannot be found in the inventory", script.ParameterTypeName)); } IDictionary<string, SqlColumnInfo> columnInfos; ISerializationTypeInfo info = serializationTypeInfoProvider.GetSerializationTypeInfo(structuredType); if (info.SimpleConverter != null) { string columnName = createTableTypeScript.TableDefinitions.OfType<TableColumnDefinition>().First(d => d.ColumnDefinition is TypedColumnDefinition).ColumnName.Value; columnInfos = new Dictionary<string, SqlColumnInfo>(1); columnInfos.Add(columnName, new SqlColumnInfo(typeMappingProvider.GetMapping(structuredType), columnName, info.SimpleConverter)); } else { columnInfos = typeMappingProvider.GetMapping(structuredType).Columns; Attribute[] mappingAttributes = Attribute.GetCustomAttributes(param, typeof(SqlMappingAttribute), true); if ((mappingAttributes != null) && (mappingAttributes.Length > 0)) { IDictionary<string, SqlColumnInfo> mappedColumnInfos = new Dictionary<string, SqlColumnInfo>(columnInfos); foreach (SqlMappingAttribute mappingAttribute in mappingAttributes) { mappedColumnInfos[mappingAttribute.TableTypeColumn] = columnInfos[mappingAttribute.SqlColumn]; } columnInfos = mappedColumnInfos; } } structuredSchema = new StructuredParameterSchema(createTableTypeScript, columnInfos); } #warning Maybe implement more type compatibility checks for arguments here // if ((sqlType == SqlDbType.Udt) && string.IsNullOrEmpty(arg.UserDefinedTypeName)) { // userDefinedTypeName = SqlSerializationTypeMapping.GetClrUserDefinedTypeName(parameter.ParameterType, arg); // } }
public SerializationTypeMapping(Type type, ISerializationTypeMappingProvider typeMappingProvider) { if (type == null) { throw new ArgumentNullException("type"); } // required to enable recursive resolution of mappings typeMappingProvider.RegisterMapping(type, this); List<IMemberConverter> memberConverters = new List<IMemberConverter>(); List<MemberInfo> memberInfos = new List<MemberInfo>(); isNativeType = CheckNativeType(type); dbType = GetTypeMapping(type); if (!(type.IsPrimitive || type.IsInterface || (typeof(string) == type))) { bool hasIdentity = false; foreach (MemberInfo member in type.GetAllFieldsAndProperties()) { SqlColumnAttribute columnAttribute = SqlColumnAttributeBase.Get<SqlColumnAttribute>(member, false); Type memberType = member.GetMemberType(); if (columnAttribute != null) { AssertValidMember(member); bool isIdentity = (!hasIdentity) && (hasIdentity |= columnAttribute.Identity); IMemberConverter memberConverter; if (columnAttribute.GetCachedByIdentity) { memberConverter = new CachedMemberConverter(memberType, isIdentity, columnAttribute.Name, memberInfos.Count, columnAttribute.DateTimeKind); } else { memberConverter = MemberConverter.Get(memberType, isIdentity, columnAttribute.Name, memberInfos.Count, columnAttribute.DateTimeKind); } memberConverters.Add(memberConverter); memberInfos.Add(member); columns.Add(columnAttribute.Name, new SqlColumnInfo(member, columnAttribute.Name, memberConverter, typeMappingProvider.GetMapping(memberType))); } else if (member.IsDefined(typeof(SqlDeserializeAttribute), true)) { AssertValidMember(member); NestedMemberConverter nestedMemberConverter; if (typeof(IList).IsAssignableFrom(memberType)) { nestedMemberConverter = new NestedListMemberConverter(memberType, memberInfos.Count); } else { nestedMemberConverter = new NestedMemberConverter(memberType, memberInfos.Count); } memberConverters.Add(nestedMemberConverter); memberInfos.Add(member); hasNestedSerializers = true; #warning add support for table valued parameters and SqlDeserializeAttribute (flatten the structure to one "table") } } } members = memberInfos.ToArray(); converters = Array.AsReadOnly(memberConverters.ToArray()); methods = MembersMethods.Get(members); }