Mercurial > pub > bltoolkit
comparison Source/Reflection/MetadataProvider/AttributeMetadataProvider.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 using System; | |
2 using System.Collections; | |
3 using System.Collections.Generic; | |
4 using System.Reflection; | |
5 using BLToolkit.Data.Sql.SqlProvider; | |
6 | |
7 using BLToolkit.TypeBuilder; | |
8 | |
9 namespace BLToolkit.Reflection.MetadataProvider | |
10 { | |
11 using DataAccess; | |
12 using Extension; | |
13 using Mapping; | |
14 | |
15 public class AttributeMetadataProvider : MetadataProviderBase | |
16 { | |
17 #region Helpers | |
18 | |
19 private TypeAccessor _typeAccessor; | |
20 private object[] _mapFieldAttributes; | |
21 private object[] _nonUpdatableAttributes; | |
22 readonly object _sync = new object(); | |
23 | |
24 void EnsureMapper(TypeAccessor typeAccessor) | |
25 { | |
26 if (_typeAccessor != typeAccessor) | |
27 { | |
28 _typeAccessor = typeAccessor; | |
29 _mapFieldAttributes = null; | |
30 _nonUpdatableAttributes = null; | |
31 } | |
32 } | |
33 | |
34 protected object[] GetMapFieldAttributes(TypeAccessor typeAccessor) | |
35 { | |
36 lock (_sync) | |
37 { | |
38 EnsureMapper(typeAccessor); | |
39 | |
40 return _mapFieldAttributes ?? (_mapFieldAttributes = TypeHelper.GetAttributes(typeAccessor.Type, typeof (MapFieldAttribute))); | |
41 } | |
42 } | |
43 | |
44 object[] GetNonUpdatableAttributes(TypeAccessor typeAccessor) | |
45 { | |
46 lock (_sync) | |
47 { | |
48 EnsureMapper(typeAccessor); | |
49 | |
50 return _nonUpdatableAttributes ?? (_nonUpdatableAttributes = TypeHelper.GetAttributes(typeAccessor.Type, typeof(NonUpdatableAttribute))); | |
51 } | |
52 } | |
53 | |
54 #endregion | |
55 | |
56 #region GetFieldName | |
57 | |
58 public override string GetFieldName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
59 { | |
60 var a = member.GetAttribute<MapFieldAttribute>(); | |
61 | |
62 if (a != null && a.MapName != null) | |
63 { | |
64 isSet = true; | |
65 return a.MapName; | |
66 } | |
67 | |
68 foreach (MapFieldAttribute attr in GetMapFieldAttributes(member.TypeAccessor)) | |
69 { | |
70 if (attr.MapName != null && string.Equals(attr.OrigName, member.Name, StringComparison.InvariantCultureIgnoreCase)) | |
71 { | |
72 isSet = true; | |
73 return attr.MapName; | |
74 } | |
75 } | |
76 | |
77 return base.GetFieldName(typeExtension, member, out isSet); | |
78 } | |
79 | |
80 #endregion | |
81 | |
82 #region GetFieldStorage | |
83 | |
84 public override string GetFieldStorage(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
85 { | |
86 var a = member.GetAttribute<MapFieldAttribute>(); | |
87 | |
88 if (a != null) | |
89 { | |
90 isSet = true; | |
91 return a.Storage; | |
92 } | |
93 | |
94 foreach (MapFieldAttribute attr in GetMapFieldAttributes(member.TypeAccessor)) | |
95 { | |
96 if (string.Equals(attr.OrigName, member.Name, StringComparison.InvariantCultureIgnoreCase)) | |
97 { | |
98 isSet = true; | |
99 return attr.Storage; | |
100 } | |
101 } | |
102 | |
103 return base.GetFieldStorage(typeExtension, member, out isSet); | |
104 } | |
105 | |
106 #endregion | |
107 | |
108 #region GetInheritanceDiscriminator | |
109 | |
110 public override bool GetInheritanceDiscriminator(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
111 { | |
112 var a = member.GetAttribute<MapFieldAttribute>(); | |
113 | |
114 if (a != null) | |
115 { | |
116 isSet = true; | |
117 return a.IsInheritanceDiscriminator; | |
118 } | |
119 | |
120 foreach (MapFieldAttribute attr in GetMapFieldAttributes(member.TypeAccessor)) | |
121 { | |
122 if (string.Equals(attr.OrigName, member.Name, StringComparison.InvariantCultureIgnoreCase)) | |
123 { | |
124 isSet = true; | |
125 return attr.IsInheritanceDiscriminator; | |
126 } | |
127 } | |
128 | |
129 return base.GetInheritanceDiscriminator(typeExtension, member, out isSet); | |
130 } | |
131 | |
132 #endregion | |
133 | |
134 #region EnsureMapper | |
135 | |
136 public override void EnsureMapper(TypeAccessor typeAccessor, MappingSchema mappingSchema, EnsureMapperHandler handler) | |
137 { | |
138 foreach (MapFieldAttribute attr in GetMapFieldAttributes(typeAccessor)) | |
139 { | |
140 if (attr.OrigName != null) | |
141 handler(attr.MapName, attr.OrigName); | |
142 else | |
143 { | |
144 var ma = typeAccessor[attr.MapName]; | |
145 | |
146 foreach (MemberMapper inner in mappingSchema.GetObjectMapper(ma.Type)) | |
147 handler(string.Format(attr.Format, inner.Name), ma.Name + "." + inner.MemberName); | |
148 } | |
149 } | |
150 } | |
151 | |
152 #endregion | |
153 | |
154 #region GetMapIgnore | |
155 | |
156 public override bool GetMapIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
157 { | |
158 var attr = member.GetAttribute<MapIgnoreAttribute>() ?? (MapIgnoreAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(MapIgnoreAttribute)); | |
159 | |
160 if (attr != null) | |
161 { | |
162 isSet = true; | |
163 return attr.Ignore; | |
164 } | |
165 | |
166 if (member.GetAttribute<MapFieldAttribute>() != null || | |
167 member.GetAttribute<MapImplicitAttribute>() != null || | |
168 TypeHelper.GetFirstAttribute(member.Type, typeof(MapImplicitAttribute)) != null) | |
169 { | |
170 isSet = true; | |
171 return false; | |
172 } | |
173 | |
174 return base.GetMapIgnore(typeExtension, member, out isSet) || member.GetAttribute<AssociationAttribute>() != null; | |
175 } | |
176 | |
177 #endregion | |
178 | |
179 #region GetMapField | |
180 | |
181 public override MapFieldAttribute GetMapField(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
182 { | |
183 var attr = member.GetAttribute<MapFieldAttribute>() ?? (MapFieldAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(MapFieldAttribute)); | |
184 | |
185 if (attr != null) | |
186 { | |
187 isSet = true; | |
188 return attr; | |
189 } | |
190 | |
191 return base.GetMapField(typeExtension, member, out isSet); | |
192 } | |
193 | |
194 #endregion | |
195 | |
196 #region GetDbType | |
197 | |
198 [CLSCompliant(false)] | |
199 public override DbTypeAttribute GetDbType(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
200 { | |
201 var attr = member.GetAttribute<DbTypeAttribute>() ?? (DbTypeAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(DbTypeAttribute)); | |
202 | |
203 if (attr != null) | |
204 { | |
205 isSet = true; | |
206 return attr; | |
207 } | |
208 | |
209 return base.GetDbType(typeExtension, member, out isSet); | |
210 } | |
211 | |
212 #endregion | |
213 | |
214 #region GetPrimaryKey | |
215 | |
216 public override PrimaryKeyAttribute GetPrimaryKey(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
217 { | |
218 var attr = member.GetAttribute<PrimaryKeyAttribute>() ?? (PrimaryKeyAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(PrimaryKeyAttribute)); | |
219 | |
220 if (attr != null) | |
221 { | |
222 isSet = true; | |
223 return attr; | |
224 } | |
225 | |
226 return base.GetPrimaryKey(typeExtension, member, out isSet); | |
227 } | |
228 | |
229 #endregion | |
230 | |
231 #region GetTrimmable | |
232 | |
233 public override bool GetTrimmable(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
234 { | |
235 if (member.Type == typeof(string)) | |
236 { | |
237 var attr = member.GetAttribute<TrimmableAttribute>(); | |
238 | |
239 if (attr != null) | |
240 { | |
241 isSet = true; | |
242 return attr.IsTrimmable; | |
243 } | |
244 | |
245 attr = (TrimmableAttribute)TypeHelper.GetFirstAttribute( | |
246 member.MemberInfo.DeclaringType, typeof(TrimmableAttribute)); | |
247 | |
248 if (attr != null) | |
249 { | |
250 isSet = true; | |
251 return attr.IsTrimmable; | |
252 } | |
253 } | |
254 | |
255 return base.GetTrimmable(typeExtension, member, out isSet); | |
256 } | |
257 | |
258 #endregion | |
259 | |
260 #region GetMapValues | |
261 | |
262 public override MapValue[] GetMapValues(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
263 { | |
264 List<MapValue> list = null; | |
265 | |
266 object[] attrs = member.GetAttributes<MapValueAttribute>(); | |
267 | |
268 if (attrs != null) | |
269 { | |
270 list = new List<MapValue>(attrs.Length); | |
271 | |
272 foreach (MapValueAttribute a in attrs) | |
273 list.Add(new MapValue(a.OrigValue, a.Values)); | |
274 } | |
275 | |
276 attrs = member.GetTypeAttributes(typeof(MapValueAttribute)); | |
277 | |
278 var memberType = TypeHelper.UnwrapNullableType(member.Type); | |
279 | |
280 if (attrs != null && attrs.Length > 0) | |
281 { | |
282 if (list == null) | |
283 list = new List<MapValue>(attrs.Length); | |
284 | |
285 foreach (MapValueAttribute a in attrs) | |
286 if (a.Type == null && a.OrigValue != null && a.OrigValue.GetType() == memberType || | |
287 a.Type is Type && (Type)a.Type == memberType) | |
288 list.Add(new MapValue(a.OrigValue, a.Values)); | |
289 } | |
290 | |
291 var typeMapValues = GetMapValues(typeExtension, memberType, out isSet); | |
292 | |
293 if (list == null) | |
294 return typeMapValues; | |
295 | |
296 if (typeMapValues != null) | |
297 list.AddRange(typeMapValues); | |
298 | |
299 isSet = true; | |
300 | |
301 return list.ToArray(); | |
302 } | |
303 | |
304 const FieldAttributes EnumField = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; | |
305 | |
306 static List<MapValue> GetEnumMapValues(Type type) | |
307 { | |
308 var list = null as List<MapValue>; | |
309 var fields = type.GetFields(); | |
310 | |
311 foreach (var fi in fields) | |
312 { | |
313 if ((fi.Attributes & EnumField) == EnumField) | |
314 { | |
315 var enumAttributes = Attribute.GetCustomAttributes(fi, typeof(MapValueAttribute)); | |
316 | |
317 foreach (MapValueAttribute attr in enumAttributes) | |
318 { | |
319 if (list == null) | |
320 list = new List<MapValue>(fields.Length); | |
321 | |
322 var origValue = Enum.Parse(type, fi.Name, false); | |
323 | |
324 list.Add(new MapValue(origValue, attr.Values)); | |
325 } | |
326 } | |
327 } | |
328 | |
329 return list; | |
330 } | |
331 | |
332 public override MapValue[] GetMapValues(TypeExtension typeExtension, Type type, out bool isSet) | |
333 { | |
334 List<MapValue> list = null; | |
335 | |
336 if (TypeHelper.IsNullable(type)) | |
337 type = type.GetGenericArguments()[0]; | |
338 | |
339 if (type.IsEnum) | |
340 list = GetEnumMapValues(type); | |
341 | |
342 var attrs = TypeHelper.GetAttributes(type, typeof(MapValueAttribute)); | |
343 | |
344 if (attrs != null && attrs.Length != 0) | |
345 { | |
346 if (list == null) | |
347 list = new List<MapValue>(attrs.Length); | |
348 | |
349 for (var i = 0; i < attrs.Length; i++) | |
350 { | |
351 var a = (MapValueAttribute)attrs[i]; | |
352 list.Add(new MapValue(a.OrigValue, a.Values)); | |
353 } | |
354 } | |
355 | |
356 isSet = list != null; | |
357 | |
358 return isSet? list.ToArray(): null; | |
359 } | |
360 | |
361 #endregion | |
362 | |
363 #region GetDefaultValue | |
364 | |
365 public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
366 { | |
367 // Check member [DefaultValue(0)] | |
368 // | |
369 var attr = member.GetAttribute<DefaultValueAttribute>(); | |
370 | |
371 if (attr != null) | |
372 { | |
373 isSet = true; | |
374 return attr.Value; | |
375 } | |
376 | |
377 // Check type [DefaultValues(typeof(int), 0)] | |
378 // | |
379 var attrs = member.GetTypeAttributes(typeof(DefaultValueAttribute)); | |
380 | |
381 foreach (DefaultValueAttribute a in attrs) | |
382 if (a.Type == null && a.Value != null && a.Value.GetType() == member.Type || | |
383 a.Type != null && a.Type == member.Type) | |
384 { | |
385 isSet = true; | |
386 return a.Value; | |
387 } | |
388 | |
389 return GetDefaultValue(mappingSchema, typeExtension, member.Type, out isSet); | |
390 } | |
391 | |
392 public override object GetDefaultValue(MappingSchema mappingSchema, TypeExtension typeExtension, Type type, out bool isSet) | |
393 { | |
394 object value = null; | |
395 | |
396 if (type.IsEnum) | |
397 value = GetEnumDefaultValueFromType(type); | |
398 | |
399 if (value == null) | |
400 { | |
401 var attrs = TypeHelper.GetAttributes(type, typeof(DefaultValueAttribute)); | |
402 | |
403 if (attrs != null && attrs.Length != 0) | |
404 value = ((DefaultValueAttribute)attrs[0]).Value; | |
405 } | |
406 | |
407 isSet = value != null; | |
408 | |
409 return TypeExtension.ChangeType(value, type); | |
410 } | |
411 | |
412 private static object GetEnumDefaultValueFromType(Type type) | |
413 { | |
414 var fields = type.GetFields(); | |
415 | |
416 foreach (var fi in fields) | |
417 { | |
418 if ((fi.Attributes & EnumField) == EnumField) | |
419 { | |
420 var attrs = Attribute.GetCustomAttributes(fi, typeof(DefaultValueAttribute)); | |
421 | |
422 if (attrs.Length > 0) | |
423 return Enum.Parse(type, fi.Name, false); | |
424 } | |
425 } | |
426 | |
427 return null; | |
428 } | |
429 | |
430 #endregion | |
431 | |
432 #region GetNullable | |
433 | |
434 public override bool GetNullable(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
435 { | |
436 // Check member [Nullable(true | false)] | |
437 // | |
438 var attr1 = member.GetAttribute<NullableAttribute>(); | |
439 | |
440 if (attr1 != null) | |
441 { | |
442 isSet = true; | |
443 return attr1.IsNullable; | |
444 } | |
445 | |
446 // Check member [NullValue(0)] | |
447 // | |
448 var attr2 = member.GetAttribute<NullValueAttribute>(); | |
449 | |
450 if (attr2 != null) | |
451 return isSet = true; | |
452 | |
453 // Check type [Nullable(true || false)] | |
454 // | |
455 attr1 = (NullableAttribute)TypeHelper.GetFirstAttribute( | |
456 member.MemberInfo.DeclaringType, typeof(NullableAttribute)); | |
457 | |
458 if (attr1 != null) | |
459 { | |
460 isSet = true; | |
461 return attr1.IsNullable; | |
462 } | |
463 | |
464 // Check type [NullValues(typeof(int), 0)] | |
465 // | |
466 var attrs = member.GetTypeAttributes(typeof(NullValueAttribute)); | |
467 | |
468 foreach (NullValueAttribute a in attrs) | |
469 if (a.Type == null && a.Value != null && a.Value.GetType() == member.Type || | |
470 a.Type != null && a.Type == member.Type) | |
471 return isSet = true; | |
472 | |
473 if (member.Type.IsEnum) | |
474 return isSet = mappingSchema.GetNullValue(member.Type) != null; | |
475 | |
476 if (member.Type.IsClass) | |
477 { | |
478 var pk = member.GetAttribute<PrimaryKeyAttribute>(); | |
479 | |
480 if (pk != null) | |
481 { | |
482 isSet = false; | |
483 return false; | |
484 } | |
485 } | |
486 | |
487 return base.GetNullable(mappingSchema, typeExtension, member, out isSet); | |
488 } | |
489 | |
490 #endregion | |
491 | |
492 #region GetLazyInstance | |
493 | |
494 public override bool GetLazyInstance(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
495 { | |
496 var attr1 = member.GetAttribute<LazyInstanceAttribute>(); | |
497 | |
498 if (attr1 != null) | |
499 { | |
500 isSet = true; | |
501 return attr1.IsLazy; | |
502 } | |
503 | |
504 attr1 = (LazyInstanceAttribute)TypeHelper.GetFirstAttribute(member.MemberInfo.DeclaringType, typeof(LazyInstanceAttribute)); | |
505 | |
506 if (attr1 != null) | |
507 { | |
508 isSet = true; | |
509 return attr1.IsLazy; | |
510 } | |
511 | |
512 return base.GetLazyInstance(mappingSchema, typeExtension, member, out isSet); | |
513 } | |
514 | |
515 #endregion | |
516 | |
517 #region GetNullValue | |
518 | |
519 private static object CheckNullValue(object value, MemberAccessor member) | |
520 { | |
521 if (value is Type && (Type)value == typeof(DBNull)) | |
522 { | |
523 value = DBNull.Value; | |
524 | |
525 if (member.Type == typeof(string)) | |
526 value = null; | |
527 } | |
528 | |
529 return value; | |
530 } | |
531 | |
532 public override object GetNullValue(MappingSchema mappingSchema, TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
533 { | |
534 // Check member [NullValue(0)] | |
535 // | |
536 var attr = member.GetAttribute<NullValueAttribute>(); | |
537 | |
538 if (attr != null) | |
539 { | |
540 isSet = true; | |
541 return CheckNullValue(attr.Value, member); | |
542 } | |
543 | |
544 // Check type [NullValues(typeof(int), 0)] | |
545 // | |
546 var attrs = member.GetTypeAttributes(typeof(NullValueAttribute)); | |
547 | |
548 foreach (NullValueAttribute a in attrs) | |
549 { | |
550 if (a.Type == null && a.Value != null && a.Value.GetType() == member.Type || | |
551 a.Type != null && a.Type == member.Type) | |
552 { | |
553 isSet = true; | |
554 return CheckNullValue(a.Value, member); | |
555 } | |
556 } | |
557 | |
558 if (member.Type.IsEnum) | |
559 { | |
560 var value = CheckNullValue(mappingSchema.GetNullValue(member.Type), member); | |
561 | |
562 if (value != null) | |
563 { | |
564 isSet = true; | |
565 return value; | |
566 } | |
567 } | |
568 | |
569 isSet = false; | |
570 return null; | |
571 } | |
572 | |
573 #endregion | |
574 | |
575 #region GetDbName | |
576 | |
577 public override string GetDatabaseName(Type type, ExtensionList extensions, out bool isSet) | |
578 { | |
579 var attrs = type.GetCustomAttributes(typeof(TableNameAttribute), true); | |
580 | |
581 if (attrs.Length > 0) | |
582 { | |
583 var name = ((TableNameAttribute)attrs[0]).Database; | |
584 isSet = name != null; | |
585 return name; | |
586 } | |
587 | |
588 return base.GetDatabaseName(type, extensions, out isSet); | |
589 } | |
590 | |
591 #endregion | |
592 | |
593 #region GetTableName | |
594 | |
595 public override string GetOwnerName(Type type, ExtensionList extensions, out bool isSet) | |
596 { | |
597 var attrs = type.GetCustomAttributes(typeof(TableNameAttribute), true); | |
598 | |
599 if (attrs.Length > 0) | |
600 { | |
601 var name = ((TableNameAttribute)attrs[0]).Owner; | |
602 isSet = name != null; | |
603 return name; | |
604 } | |
605 | |
606 return base.GetOwnerName(type, extensions, out isSet); | |
607 } | |
608 | |
609 #endregion | |
610 | |
611 #region GetTableName | |
612 | |
613 public override string GetTableName(Type type, ExtensionList extensions, out bool isSet) | |
614 { | |
615 var attrs = type.GetCustomAttributes(typeof(TableNameAttribute), true); | |
616 | |
617 if (attrs.Length > 0) | |
618 { | |
619 var name = ((TableNameAttribute)attrs[0]).Name; | |
620 isSet = name != null; | |
621 return name; | |
622 } | |
623 | |
624 return base.GetTableName(type, extensions, out isSet); | |
625 } | |
626 | |
627 #endregion | |
628 | |
629 #region GetPrimaryKeyOrder | |
630 | |
631 public override int GetPrimaryKeyOrder(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) | |
632 { | |
633 var attr = member.GetAttribute<PrimaryKeyAttribute>(); | |
634 | |
635 if (attr != null) | |
636 { | |
637 isSet = true; | |
638 return attr.Order; | |
639 } | |
640 | |
641 return base.GetPrimaryKeyOrder(type, typeExt, member, out isSet); | |
642 } | |
643 | |
644 #endregion | |
645 | |
646 public override string GetSequenceName(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
647 { | |
648 var attr = member.GetAttribute<SequenceNameAttribute>(); | |
649 | |
650 if (attr != null) | |
651 { | |
652 isSet = true; | |
653 return attr.SequenceName; | |
654 } | |
655 | |
656 return base.GetSequenceName(typeExtension, member, out isSet); | |
657 } | |
658 | |
659 #region GetNonUpdatableFlag | |
660 | |
661 public override NonUpdatableAttribute GetNonUpdatableAttribute(Type type, TypeExtension typeExt, MemberAccessor member, out bool isSet) | |
662 { | |
663 var attr = member.GetAttribute<NonUpdatableAttribute>(); | |
664 | |
665 if (attr != null) | |
666 { | |
667 isSet = true; | |
668 return attr; | |
669 } | |
670 | |
671 foreach (NonUpdatableAttribute a in GetNonUpdatableAttributes(member.TypeAccessor)) | |
672 { | |
673 if (string.Equals(a.FieldName, member.Name, StringComparison.InvariantCultureIgnoreCase)) | |
674 { | |
675 isSet = true; | |
676 return a; | |
677 } | |
678 } | |
679 | |
680 return base.GetNonUpdatableAttribute(type, typeExt, member, out isSet); | |
681 } | |
682 | |
683 #endregion | |
684 | |
685 #region GetSqlIgnore | |
686 | |
687 public override bool GetSqlIgnore(TypeExtension typeExtension, MemberAccessor member, out bool isSet) | |
688 { | |
689 var attr = member.GetAttribute<SqlIgnoreAttribute>(); | |
690 | |
691 if (attr == null) | |
692 attr = (SqlIgnoreAttribute)TypeHelper.GetFirstAttribute(member.Type, typeof(SqlIgnoreAttribute)); | |
693 | |
694 if (attr != null) | |
695 { | |
696 isSet = true; | |
697 return attr.Ignore; | |
698 } | |
699 | |
700 return base.GetSqlIgnore(typeExtension, member, out isSet); | |
701 } | |
702 | |
703 #endregion | |
704 | |
705 #region GetRelations | |
706 | |
707 public override List<MapRelationBase> GetRelations(MappingSchema schema, ExtensionList typeExt, Type master, Type slave, out bool isSet) | |
708 { | |
709 var masterAccessor = TypeAccessor.GetAccessor(master); | |
710 var slaveAccessor = slave != null ? TypeAccessor.GetAccessor(slave) : null; | |
711 var relations = new List<MapRelationBase>(); | |
712 | |
713 foreach (MemberAccessor ma in masterAccessor) | |
714 { | |
715 var attr = ma.GetAttribute<RelationAttribute>(); | |
716 | |
717 if (attr == null || (slave != null && attr.Destination != slave && ma.Type != slave)) | |
718 continue; | |
719 | |
720 if (slave == null) | |
721 slaveAccessor = TypeAccessor.GetAccessor(attr.Destination ?? ma.Type); | |
722 | |
723 | |
724 var toMany = TypeHelper.IsSameOrParent(typeof(IEnumerable), ma.Type); | |
725 | |
726 if (toMany && attr.Destination == null) | |
727 throw new InvalidOperationException("Destination type should be set for enumerable relations: " + ma.Type.FullName + "." + ma.Name); | |
728 | |
729 var masterIndex = attr.MasterIndex; | |
730 var slaveIndex = attr.SlaveIndex; | |
731 | |
732 if (slaveIndex == null) | |
733 { | |
734 var accessor = toMany ? masterAccessor : slaveAccessor; | |
735 var tex = TypeExtension.GetTypeExtension(accessor.Type, typeExt); | |
736 var keys = GetPrimaryKeyFields(schema, accessor, tex); | |
737 | |
738 if (keys.Count > 0) | |
739 slaveIndex = new MapIndex(keys.ToArray()); | |
740 } | |
741 | |
742 if (slaveIndex == null) | |
743 throw new InvalidOperationException("Slave index is not set for relation: " + ma.Type.FullName + "." + ma.Name); | |
744 | |
745 if (masterIndex == null) | |
746 masterIndex = slaveIndex; | |
747 | |
748 var relation = new MapRelationBase(attr.Destination ?? ma.Type, slaveIndex, masterIndex, ma.Name); | |
749 | |
750 relations.Add(relation); | |
751 } | |
752 | |
753 isSet = true; | |
754 return relations; | |
755 } | |
756 | |
757 #endregion | |
758 | |
759 #region GetAssociation | |
760 | |
761 public override Association GetAssociation(TypeExtension typeExtension, MemberAccessor member) | |
762 { | |
763 var aa = member.GetAttribute<AssociationAttribute>(); | |
764 | |
765 if (aa == null) | |
766 return base.GetAssociation(typeExtension, member); | |
767 | |
768 return new Association( | |
769 member, | |
770 aa.GetThisKeys(), | |
771 aa.GetOtherKeys(), | |
772 aa.Storage, | |
773 aa.CanBeNull); | |
774 } | |
775 | |
776 #endregion | |
777 | |
778 #region GetInheritanceMapping | |
779 | |
780 public override InheritanceMappingAttribute[] GetInheritanceMapping(Type type, TypeExtension typeExtension) | |
781 { | |
782 var attrs = type.GetCustomAttributes(typeof(InheritanceMappingAttribute), true); | |
783 | |
784 if (attrs.Length > 0) | |
785 { | |
786 var maps = new InheritanceMappingAttribute[attrs.Length]; | |
787 | |
788 for (var i = 0; i < attrs.Length; i++) | |
789 maps[i] = (InheritanceMappingAttribute)attrs[i]; | |
790 | |
791 return maps; | |
792 } | |
793 | |
794 return base.GetInheritanceMapping(type, typeExtension); | |
795 } | |
796 | |
797 #endregion | |
798 } | |
799 } |