File: DynamicControlParameter.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 (166 lines) | stat: -rw-r--r-- 7,458 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
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
159
160
161
162
163
164
165
166
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Web.DynamicData.Util;
using System.Web.Resources;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace System.Web.DynamicData {

    /// <summary>
    /// DynamicControlParameter is similar to ControlParameter, but understainds higher level concepts.  e.g. in a 
    /// master-details scenario using a GridView and DetailsView, you only need to point the DetailsView's datasource
    /// to the GridView (using a DynamicControlParameter), and it does the right thing.  This works even for
    /// multi-part primary keys
    /// </summary>
    public class DynamicControlParameter : Parameter, IWhereParametersProvider {

        /// <summary>
        /// </summary>
        public DynamicControlParameter() { }

        /// <summary>
        /// </summary>
        public DynamicControlParameter(string controlId) { ControlId = controlId; }

        /// <summary>
        /// The ID of the control from which the parameter gets its data
        /// </summary>
        public string ControlId { get; set; }

        /// <summary>
        /// See IWhereParametersProvider.GetWhereParameters
        /// </summary>
        public virtual IEnumerable<Parameter> GetWhereParameters(IDynamicDataSource dataSource) {
            Debug.Assert(dataSource != null);

            // Find the control that the ControlParameter uses
            Control control = Misc.FindControl((Control)dataSource, ControlId);

            if (control == null) {
                throw new InvalidOperationException(String.Format(
                    CultureInfo.CurrentCulture, DynamicDataResources.DynamicControlParameter_DynamicDataSourceControlNotFound, ControlId));
            }

            // If the control is itself a parameter provider, delegate to it
            var whereParametersProvider = control as IWhereParametersProvider;
            if (whereParametersProvider != null) {
                return whereParametersProvider.GetWhereParameters(dataSource);
            }

            IControlParameterTarget paramTarget = DynamicDataManager.GetControlParameterTarget(control);

            if (paramTarget == null) {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                    DynamicDataResources.DynamicControlParameter_DynamicDataSourceControlCannotBeUsedAsParent, ControlId));
            }

            string columnName = Name;
            MetaColumn column = null;
            MetaTable table = MetaTableHelper.GetTableWithFullFallback(dataSource, HttpContext.Current.ToWrapper());
            if (!String.IsNullOrEmpty(columnName)) {
                column = table.GetColumn(columnName);
            }
            else {
                // There was no Name attribute telling us what field to filter, but maybe
                // the control given us data has that info
                column = paramTarget.FilteredColumn;
            }

            if (column == null) {
                // If there is no specific column, we're setting the primary key

                if (paramTarget.Table != table) {
                    throw new Exception(String.Format(CultureInfo.CurrentCulture,
                        DynamicDataResources.DynamicControlParameter_InvalidPK,
                        ControlId, paramTarget.Table, table.Name));
                }

                return GetPrimaryKeyControlWhereParameters(control, paramTarget);
            }
            else if (column is MetaForeignKeyColumn) {
                return GetForeignKeyControlWhereParameters(control, paramTarget, (MetaForeignKeyColumn)column);
            }
            return GetPropertyControlWhereParameters(control, paramTarget, column);
        }

        private IEnumerable<Parameter> GetPropertyControlWhereParameters(Control control,
            IControlParameterTarget paramTarget, MetaColumn column) {
            ControlParameter controlParameter = new ControlParameter() {
                Name = column.Name,
                ControlID = control.UniqueID,
                PropertyName = paramTarget.GetPropertyNameExpression(column.Name)
            };
            
            DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, column);

            yield return controlParameter;
        }

        private IEnumerable<Parameter> GetPrimaryKeyControlWhereParameters(Control control,
            IControlParameterTarget paramTarget) {

            MetaTable parentTable = paramTarget.Table;
            if (parentTable != null) {
                // For each PK column in the table, we need to create a ControlParameter
                foreach (var keyColumn in parentTable.PrimaryKeyColumns) {
                    var controlParameter = new ControlParameter() {
                        Name = keyColumn.Name,
                        ControlID = control.UniqueID,
                        PropertyName = paramTarget.GetPropertyNameExpression(keyColumn.Name)
                    };

                    DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, keyColumn);

                    yield return controlParameter;
                }
            }
        }

        private IEnumerable<Parameter> GetForeignKeyControlWhereParameters(Control control,
            IControlParameterTarget paramTarget, MetaForeignKeyColumn column) {

            MetaTable parentTable = paramTarget.Table;
            if (parentTable != null) {
                string namePrefix = String.Empty;
                // Make sure the data types match
                if (column.ColumnType != parentTable.EntityType) {
                    throw new Exception(String.Format(CultureInfo.CurrentCulture,
                        DynamicDataResources.DynamicControlParameter_DynamicDataSourceColumnNotCompatibleWithTable,
                        column.DisplayName, parentTable.Name));
                }

                // For each underlying FK, we need to create a ControlParameter
                Debug.Assert(column.ForeignKeyNames.Count == parentTable.PrimaryKeyColumns.Count);
                int index = 0;
                foreach (var fkName in column.ForeignKeyNames) {
                    MetaColumn parentTablePKColumn = parentTable.PrimaryKeyColumns[index++];

                    var controlParameter = new ControlParameter() {
                        Name = fkName,
                        ControlID = control.UniqueID,
                        PropertyName = paramTarget.GetPropertyNameExpression(parentTablePKColumn.Name)
                    };

                    DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, parentTablePKColumn);

                    yield return controlParameter;
                }
            }
        }

        /// <summary>
        /// same as base
        /// </summary>
        /// <param name="context"></param>
        /// <param name="control"></param>
        /// <returns></returns>
        protected override object Evaluate(HttpContext context, Control control) {
            // If this gets called, it means we never had a chance to expand the parameter. Give an error
            // telling the user to use a DynamicDataManager
            throw new InvalidOperationException(String.Format(
                CultureInfo.CurrentCulture, DynamicDataResources.DynamicParameter_NeedExpansion, typeof(DynamicControlParameter).Name));
        }
    }
}