| 1 |
#Region "Microsoft.VisualBasic::ed9a194d8b1d9f3b218a5301062a798e, Microsoft.VisualBasic.Core\ComponentModel\DataSource\DataFramework.vb"
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
#End Region
|
| 50 |
|
| 51 |
Imports System.Data
|
| 52 |
Imports System.Reflection
|
| 53 |
Imports System.Runtime.CompilerServices
|
| 54 |
Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel.SchemaMaps
|
| 55 |
Imports Microsoft.VisualBasic.Language
|
| 56 |
Imports Microsoft.VisualBasic.Language.Default
|
| 57 |
Imports Microsoft.VisualBasic.Scripting.Runtime.NumberConversionRoutines
|
| 58 |
Imports Microsoft.VisualBasic.Serialization
|
| 59 |
|
| 60 |
Namespace ComponentModel.DataSourceModel
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
Public Module DataFramework
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
Public ReadOnly Property Flags As IReadOnlyDictionary(Of PropertyAccess, Assert(Of PropertyInfo))
|
| 73 |
|
| 74 |
Sub New()
|
| 75 |
Flags = New Dictionary(Of PropertyAccess, Assert(Of PropertyInfo)) From {
|
| 76 |
_
|
| 77 |
{PropertyAccess.Readable, Function(p) p.CanRead},
|
| 78 |
{PropertyAccess.ReadWrite, Function(p) p.CanRead AndAlso p.CanWrite},
|
| 79 |
{PropertyAccess.Writeable, Function(p) p.CanWrite}
|
| 80 |
}
|
| 81 |
End Sub
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
Public Function Schema(Of T)(flag As PropertyAccess,
|
| 91 |
Optional nonIndex As Boolean = False,
|
| 92 |
Optional primitive As Boolean = False) As Dictionary(Of String, PropertyInfo)
|
| 93 |
|
| 94 |
With GetType(T).Schema(flag,, nonIndex)
|
| 95 |
If primitive Then
|
| 96 |
Return .Keys _
|
| 97 |
.Where(Function(k)
|
| 98 |
Return .ByRef(k).PropertyType.IsPrimitive
|
| 99 |
End Function) _
|
| 100 |
.ToDictionary(Function(key) key,
|
| 101 |
Function(key) .ByRef(key))
|
| 102 |
Else
|
| 103 |
Return .ByRef
|
| 104 |
End If
|
| 105 |
End With
|
| 106 |
End Function
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
Public Const PublicProperty As BindingFlags = BindingFlags.Public Or BindingFlags.Instance
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
Public Const PublicShared As BindingFlags = BindingFlags.Public Or BindingFlags.Static
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
<Extension>
|
| 128 |
Public Function Schema(type As Type, flag As PropertyAccess,
|
| 129 |
Optional binds As BindingFlags = PublicProperty,
|
| 130 |
Optional nonIndex As Boolean = False) As Dictionary(Of String, PropertyInfo)
|
| 131 |
|
| 132 |
Dim props As IEnumerable(Of PropertyInfo) =
|
| 133 |
type _
|
| 134 |
.GetProperties(binds) _
|
| 135 |
.ToArray
|
| 136 |
|
| 137 |
props = props _
|
| 138 |
.Where(Flags(flag).AsLambda) _
|
| 139 |
.ToArray
|
| 140 |
|
| 141 |
If nonIndex Then
|
| 142 |
props = props _
|
| 143 |
.Where(Function(p) p.GetIndexParameters.IsNullOrEmpty)
|
| 144 |
End If
|
| 145 |
|
| 146 |
Return props.ToDictionary(Function(x) x.Name)
|
| 147 |
End Function
|
| 148 |
|
| 149 |
ReadOnly alwaysTrue As DefaultValue(Of Assert(Of Object)) = New Assert(Of Object)(Function() True)
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
<Extension>
|
| 159 |
Public Function DictionaryTable(Of T)(x As T,
|
| 160 |
Optional primitiveType As Boolean = False,
|
| 161 |
Optional where As Assert(Of Object) = Nothing) As Dictionary(Of String, String)
|
| 162 |
|
| 163 |
Dim schema As Dictionary(Of String, PropertyInfo) = GetType(T).getOrCache
|
| 164 |
Dim table As New Dictionary(Of String, String)
|
| 165 |
Dim obj
|
| 166 |
|
| 167 |
where = where Or alwaysTrue
|
| 168 |
|
| 169 |
If primitiveType Then
|
| 170 |
For Each key As String In schema.Keys.ToArray
|
| 171 |
If Not schema(key).PropertyType.IsPrimitive Then
|
| 172 |
Call schema.Remove(key)
|
| 173 |
End If
|
| 174 |
Next
|
| 175 |
End If
|
| 176 |
|
| 177 |
For Each key As String In schema.Keys
|
| 178 |
obj = schema(key).GetValue(x)
|
| 179 |
|
| 180 |
If where(obj) Then
|
| 181 |
table(key) = Scripting.ToString(obj)
|
| 182 |
End If
|
| 183 |
Next
|
| 184 |
|
| 185 |
Return table
|
| 186 |
End Function
|
| 187 |
|
| 188 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
| 189 |
<Extension>
|
| 190 |
Public Function ValueTable(Of T)(x As T) As Dictionary(Of String, Object)
|
| 191 |
Return GetType(T).getOrCache _
|
| 192 |
.ToDictionary(Function(p) p.Key,
|
| 193 |
Function(p)
|
| 194 |
Return p.Value.GetValue(x)
|
| 195 |
End Function)
|
| 196 |
End Function
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
<Extension>
|
| 204 |
Private Function getOrCache(type As Type) As Dictionary(Of String, PropertyInfo)
|
| 205 |
Static schemaCache As New Dictionary(Of Type, Dictionary(Of String, PropertyInfo))
|
| 206 |
|
| 207 |
If Not schemaCache.ContainsKey(type) Then
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
schemaCache(type) = type.Schema(
|
| 212 |
PropertyAccess.Readable,
|
| 213 |
PublicProperty,
|
| 214 |
nonIndex:=True
|
| 215 |
)
|
| 216 |
End If
|
| 217 |
|
| 218 |
Return New Dictionary(Of String, PropertyInfo)(schemaCache(type))
|
| 219 |
End Function
|
| 220 |
|
| 221 |
#If NET_40 = 0 Then
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
Public ReadOnly Property StringParsers As New Dictionary(Of Type, IStringParser) From {
|
| 228 |
_
|
| 229 |
{GetType(String), Function(strValue As String) strValue},
|
| 230 |
{GetType(Boolean), AddressOf ParseBoolean},
|
| 231 |
{GetType(DateTime), Function(strValue As String) CType(strValue, DateTime)},
|
| 232 |
{GetType(Double), AddressOf Val},
|
| 233 |
{GetType(Integer), Function(strValue As String) CInt(strValue)},
|
| 234 |
{GetType(Long), Function(strValue As String) CLng(strValue)},
|
| 235 |
{GetType(Single), Function(s) CSng(Val(s))},
|
| 236 |
{GetType(Char), Function(s) s.FirstOrDefault}
|
| 237 |
}
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
Public ReadOnly Property StringBuilders As New Dictionary(Of Type, IStringBuilder) From {
|
| 244 |
_
|
| 245 |
{GetType(String), Function(s) If(s Is Nothing, "", CStr(s))},
|
| 246 |
{GetType(Boolean), AddressOf DataFramework.valueToString},
|
| 247 |
{GetType(DateTime), AddressOf DataFramework.valueToString},
|
| 248 |
{GetType(Double), AddressOf DataFramework.valueToString},
|
| 249 |
{GetType(Integer), AddressOf DataFramework.valueToString},
|
| 250 |
{GetType(Long), AddressOf DataFramework.valueToString},
|
| 251 |
{GetType(Byte), AddressOf DataFramework.valueToString},
|
| 252 |
{GetType(ULong), AddressOf DataFramework.valueToString},
|
| 253 |
{GetType(UInteger), AddressOf DataFramework.valueToString},
|
| 254 |
{GetType(Short), AddressOf DataFramework.valueToString},
|
| 255 |
{GetType(UShort), AddressOf DataFramework.valueToString},
|
| 256 |
{GetType(Char), AddressOf DataFramework.valueToString},
|
| 257 |
{GetType(Single), AddressOf DataFramework.valueToString},
|
| 258 |
{GetType(SByte), AddressOf DataFramework.valueToString}
|
| 259 |
}
|
| 260 |
|
| 261 |
Public Delegate Function CTypeDynamics(obj As Object, ConvertType As Type) As Object
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
| 273 |
Private Function valueToString(o) As String
|
| 274 |
Return CStrSafe(o)
|
| 275 |
End Function
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
| 283 |
Public Function IsPrimitive(type As Type) As Boolean
|
| 284 |
Return StringBuilders.ContainsKey(type)
|
| 285 |
End Function
|
| 286 |
|
| 287 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
| 288 |
<Extension>
|
| 289 |
Public Function IsNumericType(type As Type) As Boolean
|
| 290 |
Static numerics As Type() = {
|
| 291 |
GetType(Integer), GetType(Long), GetType(Short), GetType(Double), GetType(Byte),
|
| 292 |
GetType(UInteger), GetType(ULong), GetType(UShort), GetType(Single), GetType(SByte), GetType(Decimal)
|
| 293 |
}
|
| 294 |
Return numerics.Any(Function(num) num Is type)
|
| 295 |
End Function
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
| 303 |
<Extension>
|
| 304 |
Public Function IsComplexType(type As Type) As Boolean
|
| 305 |
Return Not type _
|
| 306 |
.Schema(PropertyAccess.NotSure, PublicProperty, True) _
|
| 307 |
.Values _
|
| 308 |
.Where(Function(t) Not IsPrimitive(t.PropertyType)) _
|
| 309 |
.FirstOrDefault Is Nothing
|
| 310 |
End Function
|
| 311 |
#End If
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
Public Function CreateObject(Of T)(source As IEnumerable(Of T)) As DataTable
|
| 322 |
Dim columns = __initSchema(GetType(T))
|
| 323 |
Dim table As New DataTable
|
| 324 |
Dim type As Type
|
| 325 |
|
| 326 |
For Each column In columns.Values
|
| 327 |
type = DirectCast(column.member, PropertyInfo).PropertyType
|
| 328 |
Call table.Columns.Add(column.Identity, type)
|
| 329 |
Next
|
| 330 |
|
| 331 |
Dim fields As IEnumerable(Of BindProperty(Of DataFrameColumnAttribute)) =
|
| 332 |
columns.Values
|
| 333 |
|
| 334 |
For Each row As T In source
|
| 335 |
Dim LQuery = LinqAPI.Exec(Of Object) _
|
| 336 |
_
|
| 337 |
() <= From column As BindProperty(Of DataFrameColumnAttribute)
|
| 338 |
In fields
|
| 339 |
Select column.GetValue(row)
|
| 340 |
|
| 341 |
Call table.Rows.Add(LQuery)
|
| 342 |
Next
|
| 343 |
|
| 344 |
Return table
|
| 345 |
End Function
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
Public Function GetValue(Of T)(DataTable As DataTable) As T()
|
| 355 |
Dim Columns = __initSchema(GetType(T))
|
| 356 |
Dim rtvlData As T() = New T(DataTable.Rows.Count - 1) {}
|
| 357 |
Dim i As Integer = 0
|
| 358 |
|
| 359 |
Dim Schema As List(Of KeyValuePair(Of Integer, PropertyInfo)) =
|
| 360 |
New List(Of KeyValuePair(Of Integer, PropertyInfo))
|
| 361 |
For Each column As DataColumn In DataTable.Columns
|
| 362 |
Dim LQuery As BindProperty(Of DataFrameColumnAttribute) =
|
| 363 |
LinqAPI.DefaultFirst(Of BindProperty(Of DataFrameColumnAttribute)) <=
|
| 364 |
From schemaColumn As BindProperty(Of DataFrameColumnAttribute)
|
| 365 |
In Columns.Values
|
| 366 |
Where String.Equals(schemaColumn.Identity, column.ColumnName)
|
| 367 |
Select schemaColumn
|
| 368 |
|
| 369 |
If Not LQuery.IsNull Then
|
| 370 |
Call Schema.Add(New KeyValuePair(Of Integer, PropertyInfo)(column.Ordinal, LQuery.member))
|
| 371 |
End If
|
| 372 |
Next
|
| 373 |
|
| 374 |
For Each row As DataRow In DataTable.Rows
|
| 375 |
Dim obj As T = Activator.CreateInstance(Of T)()
|
| 376 |
For Each column In Schema
|
| 377 |
Dim value = row.Item(column.Key)
|
| 378 |
If IsDBNull(value) OrElse value Is Nothing Then
|
| 379 |
Continue For
|
| 380 |
End If
|
| 381 |
Call column.Value.SetValue(obj, value, Nothing)
|
| 382 |
Next
|
| 383 |
|
| 384 |
rtvlData(i) = obj
|
| 385 |
i += 1
|
| 386 |
Next
|
| 387 |
Return rtvlData
|
| 388 |
End Function
|
| 389 |
|
| 390 |
Private Function __initSchema(type As Type) As Dictionary(Of String, BindProperty(Of DataFrameColumnAttribute))
|
| 391 |
Dim dataType As Type = GetType(DataFrameColumnAttribute)
|
| 392 |
Dim props As PropertyInfo() = type.GetProperties
|
| 393 |
Dim Columns = (From [property] As PropertyInfo
|
| 394 |
In props
|
| 395 |
Let attrs As Object() = [property].GetCustomAttributes(dataType, True)
|
| 396 |
Where Not attrs.IsNullOrEmpty
|
| 397 |
Select colMaps =
|
| 398 |
DirectCast(attrs.First, DataFrameColumnAttribute), [property]
|
| 399 |
Order By colMaps.Index Ascending).AsList
|
| 400 |
|
| 401 |
For Each column In Columns
|
| 402 |
If String.IsNullOrEmpty(column.colMaps.Name) Then
|
| 403 |
Call column.colMaps.SetNameValue(column.property.Name)
|
| 404 |
End If
|
| 405 |
Next
|
| 406 |
|
| 407 |
Dim unIndexColumn = (From col
|
| 408 |
In Columns
|
| 409 |
Where col.colMaps.Index <= 0
|
| 410 |
Select col
|
| 411 |
Order By col.colMaps.Name Ascending).ToArray
|
| 412 |
|
| 413 |
For Each col In unIndexColumn
|
| 414 |
Call Columns.Remove(col)
|
| 415 |
Call Columns.Add(col)
|
| 416 |
Next
|
| 417 |
|
| 418 |
Return Columns.ToDictionary(
|
| 419 |
Function(x) x.colMaps.Name,
|
| 420 |
Function(x) New BindProperty(Of DataFrameColumnAttribute)(x.colMaps, x.property))
|
| 421 |
End Function
|
| 422 |
End Module
|
| 423 |
End Namespace
|