@@ -147,35 +147,82 @@ type DesignTime private() =
147147 @@>
148148 recordType.AddMember ctor
149149
150- recordType
150+ recordType
151+
152+ static member internal GetDataRowPropertyGetterAndSetterCode ( column : Column ) =
153+ let name = column.Name
154+ if column.Nullable then
155+ let getter = QuotationsFactory.GetBody( " GetNullableValueFromDataRow" , column.TypeInfo.ClrType, name)
156+ let setter = QuotationsFactory.GetBody( " SetNullableValueInDataRow" , column.TypeInfo.ClrType, name)
157+ getter, setter
158+ else
159+ let getter = QuotationsFactory.GetBody( " GetNonNullableValueFromDataRow" , column.TypeInfo.ClrType, name)
160+ let setter = QuotationsFactory.GetBody( " SetNonNullableValueInDataRow" , column.TypeInfo.ClrType, name)
161+ getter, setter
151162
152163 static member internal GetDataRowType ( columns : Column list ) =
153164 let rowType = ProvidedTypeDefinition( " Row" , Some typeof< DataRow>)
154165
155- columns |> List.mapi( fun i col ->
156- let name = col.Name
157- if name = " " then failwithf " Column #%i doesn't have name. Only columns with names accepted. Use explicit alias." ( i + 1 )
166+ columns |> List.mapi( fun i col ->
167+
168+ if col.Name = " " then failwithf " Column #%i doesn't have name. Only columns with names accepted. Use explicit alias." ( i + 1 )
158169
159170 let propertyType = col.ClrTypeConsideringNullable
160- if col.Nullable
161- then
162- let property = ProvidedProperty( name, propertyType, GetterCode = QuotationsFactory.GetBody( " GetNullableValueFromDataRow" , col.TypeInfo.ClrType, name))
163- if not col.ReadOnly
164- then property.SetterCode <- QuotationsFactory.GetBody( " SetNullableValueInDataRow" , col.TypeInfo.ClrType, name)
165- property
166- else
167- let property = ProvidedProperty( name, propertyType, GetterCode = ( fun args -> <@@ (%% args.[ 0 ] : DataRow).[ name] @@>))
168- if not col.ReadOnly
169- then property.SetterCode <- fun args -> <@@ (%% args.[ 0 ] : DataRow).[ name] <- %% Expr.Coerce( args.[ 1 ], typeof< obj>) @@>
170- property
171+
172+ let getter , setter = DesignTime.GetDataRowPropertyGetterAndSetterCode col
173+ let property = ProvidedProperty( col.Name, propertyType, GetterCode = getter)
174+
175+ if not col.ReadOnly then
176+ // only expose a setter if the column is not readonly
177+ // note: if this is an issue, we always expose a SetValue method on the typed DataColumn itself
178+ property.SetterCode <- setter
179+
180+ property
171181 )
172182 |> rowType.AddMembers
173183
174184 rowType
175185
176- static member internal GetDataTableType dataRowType =
186+ static member internal GetDataTableType typeName dataRowType ( outputColumns : Column list ) =
177187 let tableType = ProvidedTypeBuilder.MakeGenericType( typedefof<_ DataTable>, [ dataRowType ])
178- let tableProvidedType = ProvidedTypeDefinition( " Table" , Some tableType)
188+ let tableProvidedType = ProvidedTypeDefinition( typeName, Some tableType)
189+
190+ let columnsType = ProvidedTypeDefinition( " Columns" , Some typeof< DataColumnCollection>)
191+
192+ let ctor = ProvidedConstructor([])
193+ ctor.InvokeCode <- fun args ->
194+ <@@
195+ ()
196+ @@>
197+ columnsType.AddMember ctor
198+ let columnsProperty = ProvidedProperty( " Columns" , columnsType)
199+ tableProvidedType.AddMember columnsType
200+
201+ columnsProperty.GetterCode <-
202+ fun args ->
203+ <@@
204+ let table : DataTable < DataRow > = %% args.[ 0 ]
205+ table.Columns
206+ @@>
207+
208+ tableProvidedType.AddMember columnsProperty
209+
210+ for column in outputColumns do
211+ let propertyType = ProvidedTypeDefinition( column.Name, Some typeof< DataColumn>)
212+ let property = ProvidedProperty( column.Name, propertyType)
213+
214+ property.GetterCode <-
215+ fun args ->
216+ let columnName = column.Name
217+ <@@
218+ let columns : DataColumnCollection = %% args.[ 0 ]
219+ let column = columns.[ columnName]
220+ column
221+ @@>
222+
223+ columnsType.AddMember property
224+ columnsType.AddMember propertyType
225+
179226 tableProvidedType
180227
181228 static member internal GetOutputTypes ( outputColumns : Column list , resultType , rank : ResultRank , hasOutputParameters ) =
@@ -188,7 +235,7 @@ type DesignTime private() =
188235 elif resultType = ResultType.DataTable
189236 then
190237 let dataRowType = DesignTime.GetDataRowType outputColumns
191- let dataTableType = DesignTime.GetDataTableType dataRowType
238+ let dataTableType = DesignTime.GetDataTableType " Table " dataRowType outputColumns
192239
193240 // add .Row to .Table
194241 dataTableType.AddMember dataRowType
0 commit comments