159 lines
5.5 KiB
C#
159 lines
5.5 KiB
C#
|
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
|
|||
|
}
|
|||
|
}
|