1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace System.Web.DynamicData.ModelProviders {
internal sealed class DLinqColumnProvider : ColumnProvider {
private static Regex s_varCharRegEx = new Regex(@"N?(?:Var)?Char\(([0-9]+)\)", RegexOptions.IgnoreCase); // accepts char, nchar, varchar, and nvarchar
private AttributeCollection _attributes;
private AssociationProvider _association;
private bool _isAssociation;
public DLinqColumnProvider(DLinqTableProvider table, MetaDataMember member)
: base(table) {
Member = member;
Name = member.Name;
ColumnType = GetMemberType(member);
IsPrimaryKey = member.IsPrimaryKey;
IsGenerated = member.IsDbGenerated;
_isAssociation = member.IsAssociation;
IsCustomProperty = !member.IsAssociation && Member.DbType == null;
Nullable = Member.IsAssociation ? Member.Association.IsNullable : Member.CanBeNull;
MaxLength = ProcessMaxLength(ColumnType, Member.DbType);
IsSortable = ProcessIsSortable(ColumnType, Member.DbType);
}
public override AttributeCollection Attributes {
get {
if (!Member.IsDiscriminator)
return base.Attributes;
if (_attributes == null) {
List<Attribute> newAttributes = new List<Attribute>();
bool foundScaffoldAttribute = false;
foreach (Attribute attr in base.Attributes) {
if (attr is ScaffoldColumnAttribute) {
foundScaffoldAttribute = true;
break;
}
newAttributes.Add(attr);
}
if (foundScaffoldAttribute)
_attributes = base.Attributes;
else {
newAttributes.Add(new ScaffoldColumnAttribute(false));
_attributes = new AttributeCollection(newAttributes.ToArray());
}
}
return _attributes;
}
}
// internal to facilitate unit testing
internal static int ProcessMaxLength(Type memberType, String dbType) {
// Only strings and chars that come in from a database have max lengths
if (dbType == null || (memberType != typeof(string) && Misc.RemoveNullableFromType(memberType) != typeof(char)))
return 0;
if (dbType.StartsWith("NText", StringComparison.OrdinalIgnoreCase)) {
return Int32.MaxValue >> 1; // see sql server 2005 spec for ntext
}
if (dbType.StartsWith("Text", StringComparison.OrdinalIgnoreCase)) {
return Int32.MaxValue; // see sql server 2005 spec for text
}
if (dbType.StartsWith("NVarChar(MAX)", StringComparison.OrdinalIgnoreCase)) {
return (Int32.MaxValue >> 1) - 2; // see sql server 2005 spec for nvarchar
}
if (dbType.StartsWith("VarChar(MAX)", StringComparison.OrdinalIgnoreCase)) {
return Int32.MaxValue - 2; // see sql server 2005 spec for varchar
}
Match m = s_varCharRegEx.Match(dbType);
if (m.Success) {
return Int32.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture);
}
return 0;
}
internal static bool ProcessIsSortable(Type memberType, String dbType) {
if (dbType == null)
return false;
if (memberType == typeof(string) &&
(dbType.StartsWith("Text", StringComparison.OrdinalIgnoreCase)
|| dbType.StartsWith("NText", StringComparison.OrdinalIgnoreCase))) {
return false;
}
if (memberType == typeof(Binary) && dbType.StartsWith("Image", StringComparison.OrdinalIgnoreCase)) {
return false;
}
if (memberType == typeof(XElement)) {
return false;
}
return true;
}
internal MetaDataMember Member {
get;
private set;
}
internal void Initialize() {
if (_isAssociation && _association == null) {
_association = new DLinqAssociationProvider(this);
}
}
internal bool ShouldRemove { get; set; }
private static Type GetMemberType(MetaDataMember member) {
Type type = member.Type;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(EntitySet<>)) {
return type.GetGenericArguments()[0];
}
else {
return type;
}
}
#region IEntityMember Members
public override PropertyInfo EntityTypeProperty {
get { return (PropertyInfo)Member.Member; }
}
public override AssociationProvider Association {
get {
Initialize();
return _association;
}
}
internal new bool IsForeignKeyComponent {
set {
base.IsForeignKeyComponent = value;
}
}
#endregion
}
}
|