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