1 | #Region "Microsoft.VisualBasic::49bb9d749754395e059aadbfee5ce91e, Microsoft.VisualBasic.Core\ComponentModel\DataSource\SchemaMaps\Mappings.vb" |
2 | |
3 | ' Author: |
4 | ' |
5 | ' asuka (amethyst.asuka@gcmodeller.org) |
6 | ' xie (genetics@smrucc.org) |
7 | ' xieguigang (xie.guigang@live.com) |
8 | ' |
9 | ' Copyright (c) 2018 GPL3 Licensed |
10 | ' |
11 | ' |
12 | ' GNU GENERAL PUBLIC LICENSE (GPL3) |
13 | ' |
14 | ' |
15 | ' This program is free software: you can redistribute it and/or modify |
16 | ' it under the terms of the GNU General Public License as published by |
17 | ' the Free Software Foundation, either version 3 of the License, or |
18 | ' (at your option) any later version. |
19 | ' |
20 | ' This program is distributed in the hope that it will be useful, |
21 | ' but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | ' GNU General Public License for more details. |
24 | ' |
25 | ' You should have received a copy of the GNU General Public License |
26 | ' along with this program. If not, see <http://www.gnu.org/licenses/>. |
27 | |
28 | |
29 | |
30 | ' /********************************************************************************/ |
31 | |
32 | ' Summaries: |
33 | |
34 | ' Module Mappings |
35 | ' |
36 | ' Function: FieldNameMappings, GetColumnName, (+2 Overloads) GetFields, GetSchema, GetSchemaName |
37 | ' |
38 | ' |
39 | ' /********************************************************************************/ |
40 | |
41 | #End Region |
42 | |
43 | Imports System.Data.Linq.Mapping |
44 | Imports System.Reflection |
45 | Imports System.Runtime.CompilerServices |
46 | Imports Microsoft.VisualBasic.Language |
47 | |
48 | Namespace ComponentModel.DataSourceModel.SchemaMaps |
49 | |
50 | Public Module Mappings |
51 | |
52 | <Extension> |
53 | Public Function GetSchemaName(Of T As Attribute)( |
54 | type As Type, |
55 | getName As Func(Of T, String), |
56 | Optional explict As Boolean = False) As String |
57 | |
58 | Dim attrs As Object() = type.GetCustomAttributes(GetType(T), inherit:=True) |
59 | |
60 | If attrs.IsNullOrEmpty Then |
61 | If explict Then |
62 | Return type.Name |
63 | Else |
64 | Return Nothing |
65 | End If |
66 | Else |
67 | Dim attr As T = DirectCast(attrs(Scan0), T) |
68 | Dim name As String = getName(attr) |
69 | Return name |
70 | End If |
71 | End Function |
72 | |
73 | ''' <summary> |
74 | ''' 这个只是得到最上面的一层属性值 |
75 | ''' </summary> |
76 | ''' <typeparam name="T"></typeparam> |
77 | ''' <param name="type"></param> |
78 | ''' <param name="getName"></param> |
79 | ''' <param name="explict"> |
80 | ''' 当自定义属性不存在的时候,隐式的使用域名或者属性名作为名称,否则会跳过该对象,默认是跳过该对象 |
81 | ''' </param> |
82 | ''' <returns></returns> |
83 | <Extension> |
84 | Public Function GetFields(Of T As {Attribute})(type As Type, getName As Func(Of T, String), Optional explict As Boolean = False) As BindProperty(Of T)() |
85 | Dim out As New List(Of BindProperty(Of T)) |
86 | |
87 | For Each field As FieldInfo In type.GetFields |
88 | Dim attr As T = field.GetCustomAttribute(Of T) |
89 | |
90 | If attr Is Nothing Then |
91 | If explict Then |
92 | out += New BindProperty(Of T)(field) |
93 | End If |
94 | Else |
95 | out += New BindProperty(Of T)(attr, field) With { |
96 | .Identity = getName(attr) |
97 | } |
98 | End If |
99 | Next |
100 | |
101 | For Each [property] As PropertyInfo In type.GetProperties |
102 | Dim attr As T = [property].GetCustomAttribute(Of T) |
103 | |
104 | If attr Is Nothing Then |
105 | If explict Then |
106 | out += New BindProperty(Of T)([property]) |
107 | End If |
108 | Else |
109 | out += New BindProperty(Of T)(attr, [property]) With { |
110 | .Identity = getName(attr) |
111 | } |
112 | End If |
113 | Next |
114 | |
115 | Return out |
116 | End Function |
117 | |
118 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
119 | Public Function GetFields(Of T)(Optional explict As Boolean = True) As BindProperty(Of ColumnAttribute)() |
120 | Return GetType(T).GetFields(Of ColumnAttribute)(Function(o) o.Name, explict:=explict) |
121 | End Function |
122 | |
123 | ''' <summary> |
124 | ''' 获取从目标类型定义之中的从类型成员域名称映射到列名称的哈希表 |
125 | ''' </summary> |
126 | ''' <typeparam name="T"></typeparam> |
127 | ''' <param name="explict"></param> |
128 | ''' <param name="reversed"> |
129 | ''' 当这个参数为真的时候,将会: |
130 | ''' |
131 | ''' ``` |
132 | ''' <see cref="ColumnAttribute.Name"/> => <see cref="MemberInfo.Name"/> |
133 | ''' ``` |
134 | ''' </param> |
135 | ''' <returns></returns> |
136 | Public Function FieldNameMappings(Of T)(Optional explict As Boolean = False, Optional reversed As Boolean = False) As Dictionary(Of String, String) |
137 | Dim fields As BindProperty(Of ColumnAttribute)() = GetFields(Of T)(explict) |
138 | Dim table As Dictionary(Of String, String) |
139 | |
140 | If Not reversed Then |
141 | table = fields.ToDictionary(Function(field) |
142 | ' 获取类型定义之中的成员的属性的反射名称 |
143 | Return field.member.Name |
144 | End Function, |
145 | Function(map) |
146 | ' 获取该成员上面的自定义属性之中所记录的名称 |
147 | Return map.GetColumnName |
148 | End Function) |
149 | Else |
150 | table = fields _ |
151 | .ToDictionary(Function(map) |
152 | ' 获取该成员上面的自定义属性之中所记录的名称 |
153 | Return map.GetColumnName |
154 | End Function, |
155 | Function(field) |
156 | ' 获取类型定义之中的成员的属性的反射名称 |
157 | Return field.member.Name |
158 | End Function) |
159 | End If |
160 | |
161 | Return table |
162 | End Function |
163 | |
164 | <Extension> |
165 | Public Function GetColumnName([property] As BindProperty(Of ColumnAttribute)) As String |
166 | If [property].field Is Nothing OrElse [property].field.Name.StringEmpty Then |
167 | Return [property].Identity |
168 | Else |
169 | Return [property].field.Name |
170 | End If |
171 | End Function |
172 | |
173 | <Extension> |
174 | Public Function GetSchema(Of TField As Attribute, TTable As Attribute)( |
175 | type As Type, |
176 | getTableName As Func(Of TTable, String), |
177 | getField As Func(Of TField, String), |
178 | Optional explict As Boolean = False) As Schema(Of TField) |
179 | |
180 | Return New Schema(Of TField) With { |
181 | .SchemaName = type.GetSchemaName(Of TTable)(getTableName, explict), |
182 | .Fields = type.GetFields(Of TField)(getField, explict) |
183 | } |
184 | End Function |
185 | End Module |
186 | End Namespace |