Datei: NDODLL/Mapping/FieldMap.cs

Last Commit (006a7c7)
1 //
2 // Copyright (c) 2002-2016 Mirko Matytschak
3 // (www.netdataobjects.de)
4 //
5 // Author: Mirko Matytschak
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
8 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10 // Software, and to permit persons to whom the Software is furnished to do so, subject to the following
11 // conditions:
12
13 // The above copyright notice and this permission notice shall be included in all copies or substantial portions
14 // of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21
22
23 using System;
24 using System.Reflection;
25 using System.Linq;
26 using System.Collections.Generic;
27
28 namespace NDO.Mapping
29 {
30 ····/// <summary>
31 ····/// Collects field information for persistent types. This class is used by the NDO Enhancer.
32 ····/// </summary>
33 ····public class FieldMap
34 ····{
35 ········Class cl;
36 ········Type type;
37 ········List<string>····myFields;
38 ········List<string>····myEmbeddedTypes;
39 ········List<FieldInfo> myRelations;
40
41 ········bool checkIfMappingsExist = true;
42
43 ········// used by NDOPersistenceHandler
44 ········Dictionary<string, MemberInfo> myPersistentFields;
45
46 ········/// <summary>
47 ········/// Gets all persistent fields.
48 ········/// </summary>
49 ········public Dictionary<string,MemberInfo> PersistentFields
50 ········{
51 ············get
52 ············{
53 ················GenerateFields();
54 ················return myPersistentFields;
55 ············}
56 ········}
57
58 ········/// <summary>
59 ········/// Gets all Embedded Types.
60 ········/// </summary>
61 ········public IEnumerable<string> EmbeddedTypes
62 ········{
63 ············get { return myEmbeddedTypes; }
64 ········}
65
66
67 ········/// <summary>
68 ········/// Constructor used by NDO and the Enhancer. No sanity check.
69 ········/// </summary>
70 ········/// <param name="cl"></param>
71 ········public FieldMap(Class cl)
72 ········{
73 ············this.cl = cl;
74 ············this.type = cl.SystemType;
75 ········}
76
77 ········/// <summary>
78 ········/// Constructor used by NDO.
79 ········/// </summary>
80 ········/// <param name="cl"></param>
81 ········/// <param name="checkIfMappingsExist"></param>
82 ········public FieldMap(Class cl, bool checkIfMappingsExist) : this(cl)
83 ········{
84 ············this.checkIfMappingsExist = checkIfMappingsExist;
85 ········}
86
87 ········/// <summary>
88 ········/// Constructor used by NDO.
89 ········/// </summary>
90 ········/// <param name="t"></param>
91 ········public FieldMap(Type t)
92 ········{
93 ············this.type = t;
94 ············this.cl = null;
95 ············this.checkIfMappingsExist = false;
96 ········}
97
98 ········private void AddValueType(FieldInfo parent)
99 ········{
100 ············Type t = parent.FieldType;
101
102 ············List<FieldInfo> publicFields = new List<FieldInfo>();
103 ············List<PropertyInfo> publicProps = new List<PropertyInfo>();
104
105 ············PropertyInfo[] pis = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
106 ············foreach(PropertyInfo pi in pis)
107 ············{
108 ················if (pi.CanRead && pi.CanWrite && StorableTypes.Contains(pi.PropertyType))
109 ················{
110 ····················publicProps.Add(pi);
111 ················}
112 ············}
113 ············FieldInfo[] fis = t.GetFields(BindingFlags.Public | BindingFlags.Instance);
114 ············foreach(FieldInfo fi in fis)
115 ············{
116 ················if (StorableTypes.Contains(fi.FieldType))
117 ················{
118 ····················publicFields.Add(fi);
119 ················}
120 ············}
121 ············if (publicProps.Count > 0 || publicFields.Count > 0)
122 ············{
123 ················foreach (PropertyInfo pi in publicProps)
124 ················{
125 ····················myFields.Add (parent.Name + "." + pi.Name);
126 ····················if (!myPersistentFields.ContainsKey(parent.Name + "." + pi.Name))
127 ························myPersistentFields.Add(parent.Name + "." + pi.Name, pi);
128 ················}
129 ················foreach (FieldInfo fi in publicFields)
130 ················{
131 ····················myFields.Add (parent.Name + "." + fi.Name);
132 ····················if (!myPersistentFields.ContainsKey(parent.Name + "." + fi.Name))
133 ························myPersistentFields.Add(parent.Name + "." + fi.Name, fi);
134 ················}
135 ············}
136 ········}
137
138
139 ········private void AddEmbeddedType(FieldInfo parent)
140 ········{
141 ············FieldInfo[] fis = parent.FieldType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
142 ············foreach(FieldInfo fi in fis)
143 ············{
144 ················if (fi.Name.StartsWith("_ndo"))
145 ····················continue;
146 ················Type t = fi.FieldType;
147 ················object[] attributes = fi.GetCustomAttributes(typeof(NDOTransientAttribute), false);
148 ················if (attributes.Length > 0)
149 ····················continue;
150 ················if (StorableTypes.Contains(t))
151 ················{
152 ····················string name = parent.Name + "." + fi.Name;
153 ····················myEmbeddedTypes.Add(name);
154 ····················if (!myPersistentFields.ContainsKey(name))
155 ························myPersistentFields.Add(name, fi);
156 ················}
157 ············}
158 ········}
159
160 ········private bool IsPersistentType(Type t)
161 ········{
162 ············return t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length > 0;
163 ········}
164
165 ········private void AddFields(Type t)
166 ········{
167 ············int startind = myFields.Count;
168 ············if (!IsPersistentType(t))
169 ················return;
170 ············FieldInfo[] finfos = t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
171 ············foreach(FieldInfo fi in finfos)
172 ············{
173 ················string fname;
174 ················if ((fname = fi.Name).StartsWith("_ndo"))
175 ····················continue;
176
177 ················if (!fi.IsPrivate)
178 ····················continue;
179
180 ················if (fi.IsInitOnly)
181 ····················continue;
182
183 ················Type ft = fi.FieldType;
184
185 ················// Typen, die nicht speicherbar sind.
186 ················if (ft.IsInterface)
187 ····················continue;
188
189 ················object[] attributes = fi.GetCustomAttributes(false);
190 ················bool cont = false;
191 ················foreach (System.Attribute attr in attributes)
192 ················{
193 ····················string name;
194 ····················if ((name = attr.GetType().Name) == "NDOTransientAttribute")
195 ························cont = true;
196 ····················if (name == "NDORelationAttribute")
197 ························cont = true;
198 ················}
199 ················if (cont)
 
 
 
 
 
 
200 ····················continue;
201
202 ················if (StorableTypes.Contains(ft))
203 ················{
204 ····················this.myFields.Add(fname);
205 ····················if (!myPersistentFields.ContainsKey(fname))
206 ························myPersistentFields.Add(fname, fi);
207 ················}
208 ················else if (ft.IsValueType)
209 ····················AddValueType(fi);
210 ················else if (ft.IsClass)
211 ················{
212 ····················AddEmbeddedType(fi);
213 ················}
214 ················// Alle anderen Fälle werden ignoriert
215 ············}
216 ············// Pro Klasse werden die Strings sortiert
217 ············// Sortiert wird ohne Länderberücksichtigung, sonst sortiert die
218 ············// Anwendung auf norwegischen Systemen anders als auf deutschen.
219 ············if (myFields.Count - startind > 0)
220 ············{
221 ················FieldSorter fs = new FieldSorter();
222 ················myFields.Sort(startind, myFields.Count - startind, fs);
223 ············}
224 ········}
225
226 ········private class FieldSorter : IComparer<string>
227 ········{
228 ············public int Compare(string x, string y)
229 ············{
230 ················return String.CompareOrdinal((string) x, (string) y);
231 ············}
232 ········}········
233
234 ········private void GenerateFields()
235 ········{
236 ············myPersistentFields = new Dictionary<string,MemberInfo>();
237 ············myFields = new List<string>();
238 ············this.myEmbeddedTypes = new List<string>();
239 ············AddFields(this.type);
240 ············Type t = this.type.BaseType;
241 ············int persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
242 ············while (persCount > 0)
243 ············{
244 ················AddFields(t);················
245 ················t = t.BaseType;
246 ················persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
247 ············}
248 ············// Jetzt stehen alle Felder in myFields
249
250 ············if (checkIfMappingsExist && !this.type.IsAbstract)
251 ············{
252 ················for (int i = 0; i < myFields.Count; i++)
253 ················{
254 ····················string fieldName = myFields[i];
255 ····················NDO.Mapping.Field field;
256 ····················if ((field = cl.FindField(fieldName)) != null)
257 ························myFields[i] = field.Column.Name;
258 ····················else
259 ························throw new NDOException(7, "Can't find mapping information for field " + cl.FullName + "." + myFields[i]);
260 ················}
261 ············}
262 ········}
263
264 ········/// <summary>
265 ········/// Gets all field names.
266 ········/// </summary>
267 ········public string[] Fields
268 ········{
269 ············get
270 ············{
271 ················// Wir suchen alle Fields, für die ein Mapping existieren muss.
272 ················// wir sortieren sie nach Field-Namen.
273 ················// Dann ermitteln wir die Mapping-Namen, die dann ins Array an die gleiche
274 ················// Stelle eingetragen werden.
275 ················GenerateFields();
276 ················string[] newArr = new string[myFields.Count];
277 ················int j = 0;
278 ················foreach(string s in myFields)
279 ····················newArr[j++] = s;
280 ················return newArr;
281 ············} // get
282 ········} // Fields
283
284 ········private void AddRelations(Type t)
285 ········{
286 ············var fieldInfos = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Where(fi => !fi.IsInitOnly);
287 ············foreach(FieldInfo fi in fieldInfos)
288 ············{
289 ················if (fi.GetCustomAttributes(typeof(NDORelationAttribute), false).Length > 0)
290 ····················myRelations.Add(fi);
291 ············}
292 ········}
293
294 ········private void GenerateRelations()
295 ········{
296 ············myRelations = new List<FieldInfo>();
297 ············AddRelations(this.type);
298 ············Type t = this.type.BaseType;
299 ············int persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
300 ············while (persCount > 0)
301 ············{
302 ················if (t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length > 0)
303 ····················AddRelations(t);················
304 ················t = t.BaseType;
305 ················persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
306 ············}
307 ············// Jetzt stehen alle Relations in myRelations
308
309 ············if (checkIfMappingsExist && !this.type.IsAbstract)
310 ············{
311 ················for (int i = 0; i < myRelations.Count; i++)
312 ················{
313 ····················if (cl.FindRelation(((FieldInfo)myRelations[i]).Name) == null)
314 ························throw new NDOException(8, "Can't find mapping information for relation " + cl.FullName + "." + myRelations[i] + ".");
315 ················}
316 ············}
317 ········}
318
319
320 ········/// <summary>
321 ········/// Gets all Relations of a class and its persistent subclasses.
322 ········/// </summary>
323 ········public IEnumerable<FieldInfo> Relations
324 ········{
325 ············get
326 ············{
327 ················if (myRelations == null)
328 ····················GenerateRelations();
329 ················return myRelations;
330 ············}
331 ········}
332
333
334 ····}··// class FieldMap
335 }··// Namespace
336
New Commit (15fdc4b)
1 //
2 // Copyright (c) 2002-2016 Mirko Matytschak
3 // (www.netdataobjects.de)
4 //
5 // Author: Mirko Matytschak
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
8 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10 // Software, and to permit persons to whom the Software is furnished to do so, subject to the following
11 // conditions:
12
13 // The above copyright notice and this permission notice shall be included in all copies or substantial portions
14 // of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21
22
23 using System;
24 using System.Reflection;
25 using System.Linq;
26 using System.Collections.Generic;
27
28 namespace NDO.Mapping
29 {
30 ····/// <summary>
31 ····/// Collects field information for persistent types. This class is used by the NDO Enhancer.
32 ····/// </summary>
33 ····public class FieldMap
34 ····{
35 ········Class cl;
36 ········Type type;
37 ········List<string>····myFields;
38 ········List<string>····myEmbeddedTypes;
39 ········List<FieldInfo> myRelations;
40
41 ········bool checkIfMappingsExist = true;
42
43 ········// used by NDOPersistenceHandler
44 ········Dictionary<string, MemberInfo> myPersistentFields;
45
46 ········/// <summary>
47 ········/// Gets all persistent fields.
48 ········/// </summary>
49 ········public Dictionary<string,MemberInfo> PersistentFields
50 ········{
51 ············get
52 ············{
53 ················GenerateFields();
54 ················return myPersistentFields;
55 ············}
56 ········}
57
58 ········/// <summary>
59 ········/// Gets all Embedded Types.
60 ········/// </summary>
61 ········public IEnumerable<string> EmbeddedTypes
62 ········{
63 ············get { return myEmbeddedTypes; }
64 ········}
65
66
67 ········/// <summary>
68 ········/// Constructor used by NDO and the Enhancer. No sanity check.
69 ········/// </summary>
70 ········/// <param name="cl"></param>
71 ········public FieldMap(Class cl)
72 ········{
73 ············this.cl = cl;
74 ············this.type = cl.SystemType;
75 ········}
76
77 ········/// <summary>
78 ········/// Constructor used by NDO.
79 ········/// </summary>
80 ········/// <param name="cl"></param>
81 ········/// <param name="checkIfMappingsExist"></param>
82 ········public FieldMap(Class cl, bool checkIfMappingsExist) : this(cl)
83 ········{
84 ············this.checkIfMappingsExist = checkIfMappingsExist;
85 ········}
86
87 ········/// <summary>
88 ········/// Constructor used by NDO.
89 ········/// </summary>
90 ········/// <param name="t"></param>
91 ········public FieldMap(Type t)
92 ········{
93 ············this.type = t;
94 ············this.cl = null;
95 ············this.checkIfMappingsExist = false;
96 ········}
97
98 ········private void AddValueType(FieldInfo parent)
99 ········{
100 ············Type t = parent.FieldType;
101
102 ············List<FieldInfo> publicFields = new List<FieldInfo>();
103 ············List<PropertyInfo> publicProps = new List<PropertyInfo>();
104
105 ············PropertyInfo[] pis = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
106 ············foreach(PropertyInfo pi in pis)
107 ············{
108 ················if (pi.CanRead && pi.CanWrite && StorableTypes.Contains(pi.PropertyType))
109 ················{
110 ····················publicProps.Add(pi);
111 ················}
112 ············}
113 ············FieldInfo[] fis = t.GetFields(BindingFlags.Public | BindingFlags.Instance);
114 ············foreach(FieldInfo fi in fis)
115 ············{
116 ················if (StorableTypes.Contains(fi.FieldType))
117 ················{
118 ····················publicFields.Add(fi);
119 ················}
120 ············}
121 ············if (publicProps.Count > 0 || publicFields.Count > 0)
122 ············{
123 ················foreach (PropertyInfo pi in publicProps)
124 ················{
125 ····················myFields.Add (parent.Name + "." + pi.Name);
126 ····················if (!myPersistentFields.ContainsKey(parent.Name + "." + pi.Name))
127 ························myPersistentFields.Add(parent.Name + "." + pi.Name, pi);
128 ················}
129 ················foreach (FieldInfo fi in publicFields)
130 ················{
131 ····················myFields.Add (parent.Name + "." + fi.Name);
132 ····················if (!myPersistentFields.ContainsKey(parent.Name + "." + fi.Name))
133 ························myPersistentFields.Add(parent.Name + "." + fi.Name, fi);
134 ················}
135 ············}
136 ········}
137
138
139 ········private void AddEmbeddedType(FieldInfo parent)
140 ········{
141 ············FieldInfo[] fis = parent.FieldType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
142 ············foreach(FieldInfo fi in fis)
143 ············{
144 ················if (fi.Name.StartsWith("_ndo"))
145 ····················continue;
146 ················Type t = fi.FieldType;
147 ················object[] attributes = fi.GetCustomAttributes(typeof(NDOTransientAttribute), false);
148 ················if (attributes.Length > 0)
149 ····················continue;
150 ················if (StorableTypes.Contains(t))
151 ················{
152 ····················string name = parent.Name + "." + fi.Name;
153 ····················myEmbeddedTypes.Add(name);
154 ····················if (!myPersistentFields.ContainsKey(name))
155 ························myPersistentFields.Add(name, fi);
156 ················}
157 ············}
158 ········}
159
160 ········private bool IsPersistentType(Type t)
161 ········{
162 ············return t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length > 0;
163 ········}
164
165 ········private void AddFields(Type t)
166 ········{
167 ············int startind = myFields.Count;
168 ············if (!IsPersistentType(t))
169 ················return;
170 ············FieldInfo[] finfos = t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
171 ············foreach(FieldInfo fi in finfos)
172 ············{
173 ················string fname;
174 ················if ((fname = fi.Name).StartsWith("_ndo"))
175 ····················continue;
176
177 ················if (!fi.IsPrivate)
178 ····················continue;
179
180 ················if (fi.IsInitOnly)
181 ····················continue;
182
 
 
 
 
 
 
183 ················object[] attributes = fi.GetCustomAttributes(false);
184 ················bool cont = false;
185 ················foreach (System.Attribute attr in attributes)
186 ················{
187 ····················string name;
188 ····················if ((name = attr.GetType().Name) == "NDOTransientAttribute")
189 ························cont = true;
190 ····················if (name == "NDORelationAttribute")
191 ························cont = true;
192 ················}
193 ················if (cont)
194 ····················continue;
195
196 ················Type ft = fi.FieldType;
197
198 ················// Typen, die nicht speicherbar sind.
199 ················if (ft.IsInterface)
200 ····················continue;
201
202 ················if (StorableTypes.Contains(ft))
203 ················{
204 ····················this.myFields.Add(fname);
205 ····················if (!myPersistentFields.ContainsKey(fname))
206 ························myPersistentFields.Add(fname, fi);
207 ················}
208 ················else if (ft.IsValueType)
209 ····················AddValueType(fi);
210 ················else if (ft.IsClass)
211 ················{
212 ····················AddEmbeddedType(fi);
213 ················}
214 ················// Alle anderen Fälle werden ignoriert
215 ············}
216 ············// Pro Klasse werden die Strings sortiert
217 ············// Sortiert wird ohne Länderberücksichtigung, sonst sortiert die
218 ············// Anwendung auf norwegischen Systemen anders als auf deutschen.
219 ············if (myFields.Count - startind > 0)
220 ············{
221 ················FieldSorter fs = new FieldSorter();
222 ················myFields.Sort(startind, myFields.Count - startind, fs);
223 ············}
224 ········}
225
226 ········private class FieldSorter : IComparer<string>
227 ········{
228 ············public int Compare(string x, string y)
229 ············{
230 ················return String.CompareOrdinal((string) x, (string) y);
231 ············}
232 ········}········
233
234 ········private void GenerateFields()
235 ········{
236 ············myPersistentFields = new Dictionary<string,MemberInfo>();
237 ············myFields = new List<string>();
238 ············this.myEmbeddedTypes = new List<string>();
239 ············AddFields(this.type);
240 ············Type t = this.type.BaseType;
241 ············int persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
242 ············while (persCount > 0)
243 ············{
244 ················AddFields(t);················
245 ················t = t.BaseType;
246 ················persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
247 ············}
248 ············// Jetzt stehen alle Felder in myFields
249
250 ············if (checkIfMappingsExist && !this.type.IsAbstract)
251 ············{
252 ················for (int i = 0; i < myFields.Count; i++)
253 ················{
254 ····················string fieldName = myFields[i];
255 ····················NDO.Mapping.Field field;
256 ····················if ((field = cl.FindField(fieldName)) != null)
257 ························myFields[i] = field.Column.Name;
258 ····················else
259 ························throw new NDOException(7, "Can't find mapping information for field " + cl.FullName + "." + myFields[i]);
260 ················}
261 ············}
262 ········}
263
264 ········/// <summary>
265 ········/// Gets all field names.
266 ········/// </summary>
267 ········public string[] Fields
268 ········{
269 ············get
270 ············{
271 ················// Wir suchen alle Fields, für die ein Mapping existieren muss.
272 ················// wir sortieren sie nach Field-Namen.
273 ················// Dann ermitteln wir die Mapping-Namen, die dann ins Array an die gleiche
274 ················// Stelle eingetragen werden.
275 ················GenerateFields();
276 ················string[] newArr = new string[myFields.Count];
277 ················int j = 0;
278 ················foreach(string s in myFields)
279 ····················newArr[j++] = s;
280 ················return newArr;
281 ············} // get
282 ········} // Fields
283
284 ········private void AddRelations(Type t)
285 ········{
286 ············var fieldInfos = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Where(fi => !fi.IsInitOnly);
287 ············foreach(FieldInfo fi in fieldInfos)
288 ············{
289 ················if (fi.GetCustomAttributes(typeof(NDORelationAttribute), false).Length > 0)
290 ····················myRelations.Add(fi);
291 ············}
292 ········}
293
294 ········private void GenerateRelations()
295 ········{
296 ············myRelations = new List<FieldInfo>();
297 ············AddRelations(this.type);
298 ············Type t = this.type.BaseType;
299 ············int persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
300 ············while (persCount > 0)
301 ············{
302 ················if (t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length > 0)
303 ····················AddRelations(t);················
304 ················t = t.BaseType;
305 ················persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length;
306 ············}
307 ············// Jetzt stehen alle Relations in myRelations
308
309 ············if (checkIfMappingsExist && !this.type.IsAbstract)
310 ············{
311 ················for (int i = 0; i < myRelations.Count; i++)
312 ················{
313 ····················if (cl.FindRelation(((FieldInfo)myRelations[i]).Name) == null)
314 ························throw new NDOException(8, "Can't find mapping information for relation " + cl.FullName + "." + myRelations[i] + ".");
315 ················}
316 ············}
317 ········}
318
319
320 ········/// <summary>
321 ········/// Gets all Relations of a class and its persistent subclasses.
322 ········/// </summary>
323 ········public IEnumerable<FieldInfo> Relations
324 ········{
325 ············get
326 ············{
327 ················if (myRelations == null)
328 ····················GenerateRelations();
329 ················return myRelations;
330 ············}
331 ········}
332
333
334 ····}··// class FieldMap
335 }··// Namespace
336