InheritanceRules.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Linq;
  9. using System.Data.Linq.Mapping;
  10. using System.Data.Linq.Provider;
  11. namespace System.Data.Linq.SqlClient {
  12. /// <summary>
  13. /// This class defines the rules for inheritance behaviors. The rules:
  14. ///
  15. /// (1) The same field may not be mapped to different database columns.
  16. /// The DistinguishedMemberName and AreSameMember methods describe what 'same' means between two MemberInfos.
  17. /// (2) Discriminators held in fixed-length fields in the database don't need
  18. /// to be manually padded in inheritance mapping [InheritanceMapping(Code='x')].
  19. ///
  20. /// </summary>
  21. static class InheritanceRules {
  22. /// <summary>
  23. /// Creates a name that is the same when the member should be considered 'same'
  24. /// for the purposes of the inheritance feature.
  25. /// </summary>
  26. internal static object DistinguishedMemberName(MemberInfo mi) {
  27. PropertyInfo pi = mi as PropertyInfo;
  28. FieldInfo fi = mi as FieldInfo;
  29. if (fi != null) {
  30. // Human readable variant:
  31. // return "fi:" + mi.Name + ":" + mi.DeclaringType;
  32. return new MetaPosition(mi);
  33. }
  34. else if (pi != null) {
  35. MethodInfo meth = null;
  36. if (pi.CanRead) {
  37. meth = pi.GetGetMethod();
  38. }
  39. if (meth == null && pi.CanWrite) {
  40. meth = pi.GetSetMethod();
  41. }
  42. bool isVirtual = meth != null && meth.IsVirtual;
  43. // Human readable variant:
  44. // return "pi:" + mi.Name + ":" + (isVirtual ? "virtual" : mi.DeclaringType.ToString());
  45. if (isVirtual) {
  46. return mi.Name;
  47. } else {
  48. return new MetaPosition(mi);
  49. }
  50. }
  51. else {
  52. throw Error.ArgumentOutOfRange("mi");
  53. }
  54. }
  55. /// <summary>
  56. /// Compares two MemberInfos for 'same-ness'.
  57. /// </summary>
  58. internal static bool AreSameMember(MemberInfo mi1, MemberInfo mi2) {
  59. return DistinguishedMemberName(mi1).Equals(DistinguishedMemberName(mi2));
  60. }
  61. /// <summary>
  62. /// The representation of a inheritance code when mapped to a specific provider type.
  63. /// </summary>
  64. internal static object InheritanceCodeForClientCompare(object rawCode, System.Data.Linq.SqlClient.ProviderType providerType) {
  65. // If its a fixed-size string type in the store then pad it with spaces so that
  66. // comparing the string on the client agrees with the value returnd on the store.
  67. if (providerType.IsFixedSize && rawCode.GetType()==typeof(string)) {
  68. string s = (string) rawCode;
  69. if (providerType.Size.HasValue && s.Length!=providerType.Size) {
  70. s = s.PadRight(providerType.Size.Value).Substring(0,providerType.Size.Value);
  71. }
  72. return s;
  73. }
  74. return rawCode;
  75. }
  76. }
  77. }