Skip to content

Instantly share code, notes, and snippets.

@Ellyll
Last active May 9, 2020 09:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ellyll/e03f6be454fe392cd31c2e3444e73323 to your computer and use it in GitHub Desktop.
Save Ellyll/e03f6be454fe392cd31c2e3444e73323 to your computer and use it in GitHub Desktop.
F# function that takes a sequence (e.g. List) and returns a DataTable (with support for the F# Option type)
open System
open System.Data
open System.ComponentModel
let createDataTable (data: seq<'T>) : DataTable =
let table = new DataTable()
let props = TypeDescriptor.GetProperties(typeof<'T>)
// Add columns
for prop in props do
if prop.PropertyType.IsGenericType then
let genericType = prop.PropertyType.GetGenericTypeDefinition()
let propType =
if genericType = typedefof<Nullable<_>> then
Nullable.GetUnderlyingType(prop.PropertyType)
elif genericType = typedefof<Option<_>> then
prop.PropertyType.GetGenericArguments().[0]
else
prop.PropertyType
table.Columns.Add(prop.Name, propType) |> ignore
else
table.Columns.Add(prop.Name, prop.PropertyType) |> ignore
// Add data rows
for item in data do
let values =
[|
for prop in props ->
let valueIn = prop.GetValue(item)
if prop.PropertyType.IsGenericType
&& (prop.PropertyType.GetGenericTypeDefinition()) = typedefof<Option<_>> then
// Handle Option type
let isSome = prop.PropertyType.GetProperty("IsSome").GetValue(null, [| valueIn |]) :?> bool
if isSome then
prop.PropertyType.GetProperty("Value").GetValue(valueIn)
else
valueIn
else
valueIn
|]
table.Rows.Add(values) |> ignore
// Return the created table
table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment