File: DLinqTableProvider.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (85 lines) | stat: -rw-r--r-- 3,344 bytes parent folder | download | duplicates (9)
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
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace System.Web.DynamicData.ModelProviders {
    internal sealed class DLinqTableProvider : TableProvider {
        private ReadOnlyCollection<ColumnProvider> _roColumns;
        private List<ColumnProvider> _columns;
        private MetaType _rowType;
        private PropertyInfo _prop;

        public DLinqTableProvider(DLinqDataModelProvider dataModel, MetaType rowType, string name, PropertyInfo prop)
            : base(dataModel) {
            _prop = prop;
            _rowType = rowType;
            Name = name;
            DataContextPropertyName = prop.Name;
            EntityType = rowType.Type;
            ParentEntityType = rowType.InheritanceBase != null ? rowType.InheritanceBase.Type : null;
            RootEntityType = rowType.Table.RowType.Type;

            _columns = new List<ColumnProvider>();
            var members = new List<MetaDataMember>(rowType.DataMembers);

            // Add in base-class-first order (not the typical derived-class-first order)
            foreach (PropertyInfo propInfo in GetOrderedProperties(rowType.Type)) {
                MetaDataMember member = members.FirstOrDefault(m => m.Member.Name == propInfo.Name);
                if (member != null) {
                    AddColumn(dataModel, member, propInfo);
                    members.Remove(member);
                }
            }

            // Anything we might've missed, tack it onto the end
            foreach (MetaDataMember member in members) {
                AddColumn(dataModel, member, (PropertyInfo)member.Member);
            }

            _roColumns = new ReadOnlyCollection<ColumnProvider>(_columns);
        }

        private void AddColumn(DLinqDataModelProvider dataModel, MetaDataMember member, PropertyInfo propInfo) {
            var publicGetAccessor = propInfo.GetGetMethod();
            if (publicGetAccessor == null) {
                // the property at least needs to have a public getter, otherwise databinding will not work
                return;
            }

            DLinqColumnProvider column = new DLinqColumnProvider(this, member);
            _columns.Add(column);

            if (!dataModel.ColumnLookup.ContainsKey(propInfo))
                dataModel.ColumnLookup[propInfo] = column;
        }

        private IEnumerable<PropertyInfo> GetOrderedProperties(Type type) {
            if (type == null)
                return new PropertyInfo[0];
            PropertyInfo[] props = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            return GetOrderedProperties(type.BaseType).Concat(props);
        }

        internal void Initialize() {
            _columns.ForEach(c => ((DLinqColumnProvider)c).Initialize());
            _columns.RemoveAll(c => ((DLinqColumnProvider)c).ShouldRemove);
        }

        #region IEntity Members

        public override IQueryable GetQuery(object context) {
            return (IQueryable)_prop.GetValue(context, null);
        }

        public override ReadOnlyCollection<ColumnProvider> Columns {
            get {
                return _roColumns;
            }
        }

        #endregion
    }
}