Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWebControlsDesign / System / Data / WebControls / Design / EntityDataSourceDataSelection.cs / 1305376 / EntityDataSourceDataSelection.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] // // Manages the properties that can be set on the second page of the wizard //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Entity; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Globalization; using System.Text; using System.Web.Resources.Design; using System.Web.UI.Design.Util; using System.Linq; namespace System.Web.UI.Design.WebControls { internal class EntityDataSourceDataSelection { #region Private static fields // iterator prefix used in building and parsing Select property value private static readonly string s_itKeyword = "it."; // Placeholder item to indicate (None) on the EntityTypeFilter ComboBox private static readonly EntityDataSourceEntityTypeFilterItem s_entityTypeFilterNoneItem = new EntityDataSourceEntityTypeFilterItem(Strings.Wizard_DataSelectionPanel_NoEntityTypeFilter); #endregion #region Private readonly fields private readonly EntityDataSourceDataSelectionPanel _panel; private readonly EntityDataSourceDesignerHelper _helper; #endregion #region Private fields for temporary storage of property values private readonly EntityDataSourceState _entityDataSourceState; private List_entitySetNames; private EntityDataSourceEntitySetNameItem _selectedEntitySetName; private List _entityTypeFilters; private EntityDataSourceEntityTypeFilterItem _selectedEntityTypeFilter; #region Select views // The Data Selection wizard panel can display two kinds of views of the Select property: // (1) Simple Select View: CheckedListBox with a list of available entity type properties // (2) Advanced Select View: TextBox that allows any statement to be entered (no validation) // // When either view is visible to the user, the fields shown below for that view should be non-null, and the fields // for the other view should be null. // Simple Select View // _selectedEntityTypeProperties contains a set of indexes of properties in _entityTypeProperties private List _entityTypeProperties; private List _selectedEntityTypeProperties; // Advanced Select View private string _select; #endregion private bool _enableInsert; private bool _enableUpdate; private bool _enableDelete; private readonly EntityDataSourceWizardForm _wizardForm; #endregion #region Constructors internal EntityDataSourceDataSelection(EntityDataSourceDataSelectionPanel panel, EntityDataSourceWizardForm wizard, EntityDataSourceDesignerHelper designerHelper, EntityDataSourceState entityDataSourceState) { _panel = panel; _panel.Register(this); _helper = designerHelper; _entityDataSourceState = entityDataSourceState; _wizardForm = wizard; } #endregion #region Events // Event handler to process notifications when a DefaultContainerName is selected on the ObjectContext configuration panel internal void ContainerNameChangedHandler(object sender, EntityDataSourceContainerNameItem newContainerName) { // Load the entity sets for this container, don't select anything initially in the list LoadEntitySetNames(newContainerName, null); // Reset the other controls that depend on the value of EntitySet LoadEntityTypeFilters(null, null); LoadSelect(String.Empty); } #endregion #region Methods to manage temporary state and wizard contents // Used when the wizard is launched, to load existing property values from data source control internal void LoadState() { LoadEntitySetNames(_helper.GetEntityContainerItem(_entityDataSourceState.DefaultContainerName), _entityDataSourceState.EntitySetName); LoadEntityTypeFilters(_selectedEntitySetName, _entityDataSourceState.EntityTypeFilter); LoadSelect(_entityDataSourceState.Select); LoadInsertUpdateDelete(); } // Save current wizard settings back to the EntityDataSourceState internal void SaveState() { SaveEntitySetName(); SaveEntityTypeFilter(); SaveSelect(); SaveInsertUpdateDelete(); SaveEnableFlattening(); } #region EntitySetName // Find the specified entitySetName in the list or add it if it's not there private EntityDataSourceEntitySetNameItem FindEntitySetName(string entitySetName) { if (!String.IsNullOrEmpty(entitySetName)) { EntityDataSourceEntitySetNameItem entitySetToSelect = null; foreach (EntityDataSourceEntitySetNameItem entitySetNameItem in _entitySetNames) { // Ignore case here when searching the list for a matching item, but set the temporary state property to the // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. if (String.Equals(entitySetNameItem.EntitySetName, entitySetName, StringComparison.OrdinalIgnoreCase)) { entitySetToSelect = entitySetNameItem; } } // didn't find a matching entityset, so just create a placeholder for one using the specified name and add it to the list if (entitySetToSelect == null) { entitySetToSelect = new EntityDataSourceEntitySetNameItem(entitySetName); _entitySetNames.Add(entitySetToSelect); } Debug.Assert(entitySetToSelect != null, "expected a non-null EntityDataSourceEntitySetNameItem"); return entitySetToSelect; } return null; } // Populates the EntitySetName combobox with all of the discoverable EntitySets for the specified container. // If the specified entitySetName is not empty, it is added to the list and selected as the initial value // containerNameItem may not be backed by a real EntityContainer, in which case there is no way to look up the EntitySet in metadata // devnote: This method should not automatically reset EntityTypeFilter and Select because it can be used to load the initial state // for the form, in which case we need to preserve any values that are already set on the data source control. private void LoadEntitySetNames(EntityDataSourceContainerNameItem containerNameItem, string entitySetName) { // If this is a container that we found in the project's metadata, get a list of EntitySets for that container if (containerNameItem != null && containerNameItem.EntityContainer != null) { _entitySetNames = _helper.GetEntitySets(containerNameItem.EntityContainer, false /*sortResults*/); // Try to find the specified entityset in list and add it if it isn't there _selectedEntitySetName = FindEntitySetName(entitySetName); } else { // if this is an unknown container, there is no way to find a list of entitysets from metadata // so just create a new list and placeholder for the specified entityset _entitySetNames = new List (); if (!String.IsNullOrEmpty(entitySetName)) { _selectedEntitySetName = new EntityDataSourceEntitySetNameItem(entitySetName); _entitySetNames.Add(_selectedEntitySetName); } else { _selectedEntitySetName = null; } } // Sort the list now, after we may have added one above _entitySetNames.Sort(); // Update the controls _panel.SetEntitySetNames(_entitySetNames); _panel.SetSelectedEntitySetName(_selectedEntitySetName); } // Set EntitySetName in temporary storage internal void SelectEntitySetName(EntityDataSourceEntitySetNameItem selectedEntitySet) { _selectedEntitySetName = selectedEntitySet; // Load the types for the selected EntitySet, don't select one initially LoadEntityTypeFilters(selectedEntitySet, null); // Reinitialize the Select control with a list of properties, don't preserve any existing Select value LoadSelect(String.Empty); } private void SaveEntitySetName() { if (_selectedEntitySetName != null) { _entityDataSourceState.EntitySetName = _selectedEntitySetName.EntitySetName; } else { _entityDataSourceState.EntitySetName = String.Empty; } } #endregion #region EntityTypeFilter // Populate a list with the base type for the EntitySet plus all derived types, and a special entry to indicate no filter // devnote: This method should not automatically reset Select because it can be used to load the initial state // for the form, in which case we need to preserve any values that are already set on the data source control. private void LoadEntityTypeFilters(EntityDataSourceEntitySetNameItem entitySetItem, string entityTypeFilter) { // If this is an EntitySet that we found in the project's metadata, get the type information if (entitySetItem != null && entitySetItem.EntitySet != null) { _entityTypeFilters = _helper.GetEntityTypeFilters(entitySetItem.EntitySet.ElementType, false /*sortResults*/); // add (None) to the beginning of the list _entityTypeFilters.Insert(0, s_entityTypeFilterNoneItem); // Try to find the specified type in list and add it if it isn't there _selectedEntityTypeFilter = FindEntityTypeFilter(entityTypeFilter); } else { // if this is an unknown EntitySet, there is no way to find a list of types from metadata // so just create a new list and placeholder for the specified type _entityTypeFilters = new List (); _entityTypeFilters.Add(s_entityTypeFilterNoneItem); if (!String.IsNullOrEmpty(entityTypeFilter)) { _selectedEntityTypeFilter = new EntityDataSourceEntityTypeFilterItem(entityTypeFilter); _entityTypeFilters.Add(_selectedEntityTypeFilter); } else { _selectedEntityTypeFilter = s_entityTypeFilterNoneItem; } } // Sort now after we might have added items above _entityTypeFilters.Sort(); // Update the controls _panel.SetEntityTypeFilters(_entityTypeFilters); _panel.SetSelectedEntityTypeFilter(_selectedEntityTypeFilter); } // Find the specified entityTypeFilter in the list and add it if it's not there private EntityDataSourceEntityTypeFilterItem FindEntityTypeFilter(string entityTypeFilter) { if (!String.IsNullOrEmpty(entityTypeFilter)) { EntityDataSourceEntityTypeFilterItem typeToSelect = null; foreach (EntityDataSourceEntityTypeFilterItem entityTypeFilterItem in _entityTypeFilters) { // Ignore case here when searching the list for a matching item, but set the temporary state property to the // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. if (String.Equals(entityTypeFilterItem.EntityTypeName, entityTypeFilter, StringComparison.OrdinalIgnoreCase)) { typeToSelect = entityTypeFilterItem; } } // didn't find a matching type, so just create a placeholder item and add it to the list if (typeToSelect == null) { typeToSelect = new EntityDataSourceEntityTypeFilterItem(entityTypeFilter); _entityTypeFilters.Add(typeToSelect); } Debug.Assert(typeToSelect != null, "expected a non-null string for EntityTypeFilter"); return typeToSelect; } return s_entityTypeFilterNoneItem; } // Set EntityTypeFilter in temporary storage and load the Select property internal void SelectEntityTypeFilter(EntityDataSourceEntityTypeFilterItem selectedEntityTypeFilter) { _selectedEntityTypeFilter = selectedEntityTypeFilter; // Reinitialize the Select control with a list of properties, don't preserve any existing Select value LoadSelect(String.Empty); } private void SaveEntityTypeFilter() { // If (None) is selected, it is the same as an empty string on the data source control if (Object.ReferenceEquals(_selectedEntityTypeFilter, s_entityTypeFilterNoneItem)) { _entityDataSourceState.EntityTypeFilter = String.Empty; } else { _entityDataSourceState.EntityTypeFilter = _selectedEntityTypeFilter.EntityTypeName; } } #endregion #region Select // Load and parse the Select property private void LoadSelect(string select) { Debug.Assert(_selectedEntityTypeFilter != null, "_selectedEntityTypeFilter should never be null"); EntityType entityType = GetSelectedEntityType(); if (entityType != null) { // this is a real type from metadata, load its properties _entityTypeProperties = _helper.GetEntityTypeProperties(entityType); // add the 'Select All (Entity Value)' placeholder at the beginning of the list _entityTypeProperties.Insert(0, Strings.Wizard_DataSelectionPanel_SelectAllProperties); // parse the current value for the Select property to see if it can be displayed in the simple CheckedListBox view if (TryParseSelect(select)) { _select = null; // Update the controls _panel.SetEntityTypeProperties(_entityTypeProperties, _selectedEntityTypeProperties); UpdateInsertUpdateDeleteState(); return; } // else we failed to parse the select into entity type properties on the specified type, so just use the advanced select view } // else can't get a list of properties unless we have a known EntityType // if we don't have a valid entity type or couldn't parse the incoming Select value, just display the advanced TextBox view _entityTypeProperties = null; _selectedEntityTypeProperties = null; _select = select; // Update the controls _panel.SetSelect(_select); UpdateInsertUpdateDeleteState(); } // Build a value for the Select property from the selected values in the CheckedListBox // Value will be in the from "it.Property1, it.Property2, it.Property3" private string BuildSelect() { Debug.Assert(_selectedEntityTypeProperties != null && _selectedEntityTypeProperties.Count > 0, "expected non-null _selectedEntityTypeProperties with at least one value"); // 'Select All (Entity Value)' is the same thing as an empty string for the property if (_selectedEntityTypeProperties[0] == 0) { Debug.Assert(_selectedEntityTypeProperties.Count == 1, "'Select All (Entity Value)' should be the only property selected"); return String.Empty; } StringBuilder selectProperties = new StringBuilder(); bool addComma = false; foreach (int propertyIndex in _selectedEntityTypeProperties) { if (addComma) { selectProperties.Append(", "); } else { addComma = true; } selectProperties.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", s_itKeyword, EscapePropertyName(_entityTypeProperties[propertyIndex])); } return selectProperties.ToString(); } private static string EscapePropertyName(string propertyName) { return "[" + propertyName.Replace("]", "]]") + "]"; } static string UnescapePropertyName(string name) { if (name[0] == '[' && name[name.Length - 1] == ']') { return name.Substring(1, name.Length - 2).Replace("]]", "]"); } else { // else the property is not escaped at all or is not properly escaped. We can't parse it so just return. return name; } } // Parses the current Select property on the data source to see if it matches a specific format that we can use to display the properties // in the CheckedListBox in the simple select wizard view private bool TryParseSelect(string currentSelect) { bool parseSuccess = false; // gets set to true after the statement has been successfully parsed if (!String.IsNullOrEmpty(currentSelect)) { // first try to split the string up into pieces divided by commas // expects a format like the following: (extra spaces around the commas should work as well) // "it.KnownPropertyName1, it.KnownPropertyName2, it.KnownPropertyName3" string[] tokenizedSelect = currentSelect.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); bool foundUnknownProperty = false; List selectedProperties = new List (); foreach (string token in tokenizedSelect) { string propertyName = token.Trim(); // Does the current property token start with "it."? if (ReadItKeyword(propertyName)) { // Does the rest of the property token match a known property name for the selected EntityTypeFilter? int propertyIndex = ReadPropertyName(propertyName.Substring(s_itKeyword.Length)); if (propertyIndex == -1) { // the property was not known, so we can just stop looking foundUnknownProperty = true; break; } else { // this is a known property, so add its index to the list selectedProperties.Add(propertyIndex); } } else { // the property was not known, so we can just stop looking foundUnknownProperty = true; break; } } if (!foundUnknownProperty) { // if we never found anything unknown, the current list of properties is what we'll use to fill in the CheckedListBox _selectedEntityTypeProperties = selectedProperties; parseSuccess = true; } else { _selectedEntityTypeProperties = null; } } else { // if Select is empty, we just want to add 'Select All (Entity Value)' to the list _selectedEntityTypeProperties = new List (); _selectedEntityTypeProperties.Add(0); parseSuccess = true; } return parseSuccess; } // Determines if the specified propertyName starts with "it." (case-insensitive) private bool ReadItKeyword(string propertyName) { // will accept any casing of "it." here, although when the value is saved back to the property, it will be correctly lower-cased return propertyName.StartsWith(s_itKeyword, StringComparison.OrdinalIgnoreCase); } // Determines if the specified propertyName matches one of the known properties for the selected type private int ReadPropertyName(string propertyName) { for (int propIndex = 0; propIndex < _entityTypeProperties.Count; propIndex++) { // Ignore case here when searching the list for a matching item, but set the temporary state property to the // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. // Does the specified property name exactly match any of the properties for the selected EntityTypeFilter? if (String.Equals(UnescapePropertyName(propertyName), _entityTypeProperties[propIndex], StringComparison.OrdinalIgnoreCase)) { return propIndex; } } return -1; } // Add the specified property to the list of selected entity properties used to build up the Select property internal void SelectEntityProperty(int propertyIndex) { _selectedEntityTypeProperties.Add(propertyIndex); } internal void ClearAllSelectedProperties() { _selectedEntityTypeProperties.Clear(); } // Remove specified entity property index from the selected list internal void DeselectEntityProperty(int propertyIndex) { _selectedEntityTypeProperties.Remove(propertyIndex); } // Set Select property to the specified string (used with advanced select view) internal void SelectAdvancedSelect(string select) { _select = select; } private void SaveSelect() { if (_select != null) { _entityDataSourceState.Select = _select; } else { Debug.Assert(_selectedEntityTypeProperties != null, "expected _entityTypeProperties to be non-null if _select is null"); _entityDataSourceState.Select = BuildSelect(); } } #endregion #region EnableInsertUpdateDelete // Load the initial values for EnableInsert/EnableUpdate/EnableDelete CheckBoxes private void LoadInsertUpdateDelete() { SelectEnableInsert(_entityDataSourceState.EnableInsert); SelectEnableUpdate(_entityDataSourceState.EnableUpdate); SelectEnableDelete(_entityDataSourceState.EnableDelete); UpdateInsertUpdateDeleteState(); } // Set EnableDelete in temporary storage internal void SelectEnableDelete(bool enableDelete) { _enableDelete = enableDelete; } // Set EnableInsert in temporary storage internal void SelectEnableInsert(bool enableInsert) { _enableInsert = enableInsert; } // Set EnableUpdate in temporary storage internal void SelectEnableUpdate(bool enableUpdate) { _enableUpdate = enableUpdate; } private void SaveInsertUpdateDelete() { _entityDataSourceState.EnableInsert = _enableInsert; _entityDataSourceState.EnableUpdate = _enableUpdate; _entityDataSourceState.EnableDelete = _enableDelete; } /// /// Update the panel control state based on the valued of enableInsert, /// enableUpdate, enableDelete, and the selectedEntityTypeProperties /// internal void UpdateInsertUpdateDeleteState() { // Set the checkbox state for the panel controls _panel.SetEnableInsertUpdateDelete(_enableInsert, _enableUpdate, _enableDelete); // The InsertUpdateDelete panel should be enabled if: // 1. Insert, Update, or Delete is selected -OR- // 2. The EntitySelection has SelectAll checked bool enablePanel = (_enableInsert || _enableUpdate || _enableDelete || (_selectedEntityTypeProperties != null && _selectedEntityTypeProperties.Count == 1 && _selectedEntityTypeProperties[0] == 0)); _panel.SetEnableInsertUpdateDeletePanel(enablePanel); } #endregion #region EnableFlattening private EntityType GetSelectedEntityType() { EntityType entityType = null; // determine which EntityType to load properties for, based on the value selected for EntityTypeFilter if (Object.ReferenceEquals(_selectedEntityTypeFilter, s_entityTypeFilterNoneItem)) { // If (None) is selected, use the base type for the EntitySet if available if (_selectedEntitySetName != null && _selectedEntitySetName.EntitySet != null) { entityType = _selectedEntitySetName.EntitySet.ElementType; } // else the EntitySet base type is not known } else { entityType = _selectedEntityTypeFilter.EntityType; // could still be null if the type if not known in metadata } return entityType; } private void SaveEnableFlattening() { bool enableFlattening = false; EntityType entityType = GetSelectedEntityType(); if (entityType != null) { foreach (EdmMember member in entityType.Members) { // If there is a complex member, enable flattening if (member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType) { enableFlattening = true; break; } else if (member.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty) { NavigationProperty navProp = (NavigationProperty)member; if (navProp.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many) { AssociationType associationType = navProp.ToEndMember.DeclaringType as AssociationType; if (!associationType.IsForeignKey) { // If there is an independent association, enable flattening enableFlattening = true; break; } } } } } else { // Projection enableFlattening = true; } _entityDataSourceState.EnableFlattening = enableFlattening; } #endregion #endregion #region Wizard button state management internal void UpdateWizardState() { // EntitySetName must be selected and a Select must be configured or must be the empty string _wizardForm.SetCanFinish(_selectedEntitySetName != null && (_select != null || _selectedEntityTypeProperties.Count > 0)); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TraceContextEventArgs.cs
- Vector3DConverter.cs
- DBPropSet.cs
- RemotingConfiguration.cs
- ScriptServiceAttribute.cs
- HyperLinkColumn.cs
- MetadataItemCollectionFactory.cs
- UndoEngine.cs
- RectAnimationClockResource.cs
- HuffCodec.cs
- TagMapCollection.cs
- RequestCachePolicy.cs
- ValidatorAttribute.cs
- HttpPostLocalhostServerProtocol.cs
- DescendantOverDescendantQuery.cs
- WriteableBitmap.cs
- SoapClientProtocol.cs
- SQLChars.cs
- WinInetCache.cs
- SqlCrossApplyToCrossJoin.cs
- ProviderConnectionPoint.cs
- HideDisabledControlAdapter.cs
- GestureRecognitionResult.cs
- WindowsPrincipal.cs
- TimeSpanMinutesOrInfiniteConverter.cs
- ChannelHandler.cs
- VarRefManager.cs
- TreeViewImageIndexConverter.cs
- HasCopySemanticsAttribute.cs
- SqlSupersetValidator.cs
- ImageMapEventArgs.cs
- ZipPackagePart.cs
- BitmapFrameEncode.cs
- AssociationProvider.cs
- TheQuery.cs
- DesigntimeLicenseContext.cs
- ExceptionUtility.cs
- SortAction.cs
- DataGridViewButtonColumn.cs
- EncoderBestFitFallback.cs
- DiffuseMaterial.cs
- ByteAnimationUsingKeyFrames.cs
- ComplexLine.cs
- ArithmeticException.cs
- ZoneMembershipCondition.cs
- SchemaEntity.cs
- StrongTypingException.cs
- SqlProviderManifest.cs
- DesignerHelpers.cs
- BackgroundWorker.cs
- StringExpressionSet.cs
- EntityKey.cs
- Internal.cs
- WindowsFormsSynchronizationContext.cs
- XmlSubtreeReader.cs
- SetState.cs
- AddressAlreadyInUseException.cs
- DbFunctionCommandTree.cs
- SourceFileBuildProvider.cs
- SoapMessage.cs
- ColorTransformHelper.cs
- TableItemPattern.cs
- DataGridState.cs
- ObjectDataSourceMethodEventArgs.cs
- BlockCollection.cs
- ErrorView.xaml.cs
- Header.cs
- TextFormatterContext.cs
- ContentType.cs
- ValueOfAction.cs
- CqlGenerator.cs
- DataGridViewCellLinkedList.cs
- CapabilitiesPattern.cs
- XmlILModule.cs
- login.cs
- ValidateNames.cs
- ItemCollection.cs
- ApplicationActivator.cs
- PrintingPermissionAttribute.cs
- EntitySetDataBindingList.cs
- MulticastDelegate.cs
- SymbolEqualComparer.cs
- CompositeFontFamily.cs
- Attributes.cs
- UserPreferenceChangingEventArgs.cs
- EUCJPEncoding.cs
- PageThemeParser.cs
- InertiaTranslationBehavior.cs
- LogReservationCollection.cs
- CommandHelper.cs
- Rfc2898DeriveBytes.cs
- DrawingAttributes.cs
- AccessDataSource.cs
- Pair.cs
- FileReservationCollection.cs
- MenuItemCollection.cs
- XmlMemberMapping.cs
- M3DUtil.cs
- FontFamilyIdentifier.cs
- WmpBitmapEncoder.cs