public void Visit(EndProperty instruction) { executeInstruction(() => { _propertyDef = null; var currentGeneric = _genericStack.Peek(); if (_currentFieldMap == null) { return; } currentGeneric.ClarifyGeneric.DataFields.AddRange(_currentFieldMap.FieldNames); if (currentGeneric.Model.ModelName != _modelStack.Peek().ModelName) { currentGeneric.Model.AddFieldMap(_currentFieldMap); } else { currentGeneric.AddFieldMap(_currentFieldMap); } _currentFieldMap = null; }); }
/// <summary> /// Creates a ScalarProperty in the given EndProperty. /// </summary> /// <param name="end">The EndProperty to place this ScalarProperty; cannot be null.</param> /// <param name="entityProperty">This must be a valid Property from the C-Model.</param> /// <param name="tableColumn">This must be a valid Property from the S-Model.</param> /// <param name="enforceConstraints">If true checks/updates conditions on association mappings and referential constraints</param> internal CreateEndScalarPropertyCommand( EndProperty endProperty, Property entityProperty, Property tableColumn, bool enforceConstraints) { Initialize(entityProperty, tableColumn, enforceConstraints); CommandValidation.ValidateEndProperty(endProperty); _endProperty = endProperty; }
internal void CheckAssociationForUnmappedEntityTypeKeys(Association a) { // This check verifies that each key property on the end of the association is mapped. foreach (var end in a.AssociationEnds()) { var et = end.Type.Target; if (et != null && et.Key != null) { EndProperty endProperty = null; var associationSetEnd = GetFirstAntiDependencyOfType <AssociationSetEnd>(end); if (associationSetEnd != null) { endProperty = GetFirstAntiDependencyOfType <EndProperty>(associationSetEnd); } if (endProperty != null) { var severity = ValidationHelper.IsStorageModelEmpty(et.Artifact) ? ErrorInfo.Severity.WARNING : ErrorInfo.Severity.ERROR; // check each key property in the entity type foreach (var pr in et.Key.PropertyRefs) { var found = false; var prop = pr.Name.Target; if (prop != null) { foreach (var sp in endProperty.ScalarProperties()) { if (sp.Name.Target != null) { if (sp.Name.Target.Equals(prop)) { found = true; } } } if (!found) { // didn't find the key property mapped so add an error var msg = String.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_UnmappedAssociationEndKey, prop.LocalName.Value); ArtifactSet.AddError( new ErrorInfo( severity, msg, a, ErrorCodes.ESCHER_VALIDATOR_UNMAPPED_ASSOCIATION_END_KEY, ErrorClass.Escher_MSL)); } } } } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { var end = new EndProperty(AssociationSetMapping, null); end.Name.SetRefName(AssociationSetEnd); AssociationSetMapping.AddEndProperty(end); XmlModelHelper.NormalizeAndResolve(end); Debug.Assert(end.Name.Target != null, "Could not resolve AssociationSetEnd in an EndProperty"); _created = end; }
protected override void ProcessPreReqCommands() { // if we don't have an EndProperty, see if there is a prereq registered; don't try if we have the ASM and ASE // since this means that we should create an end later inside Invoke() if (_associationSetMapping == null && _associationSetEnd == null && _endProperty == null) { var prereq = GetPreReqCommand(CreateEndPropertyCommand.PrereqId) as CreateEndPropertyCommand; if (prereq != null) { _endProperty = prereq.EndProperty; } Debug.Assert(_endProperty != null, "We didn't get a good EndProperty out of the Command"); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_endProperty == null) { var cmd = new CreateEndPropertyCommand(_associationSetMapping, _associationSetEnd); CommandProcessor.InvokeSingleCommand(cpc, cmd); _endProperty = cmd.EndProperty; } Debug.Assert(_endProperty != null, "_endProperty should not be null"); if (_endProperty == null) { throw new CannotLocateParentItemException(); } var sp = new ScalarProperty(_endProperty, null); sp.Name.SetRefName(_entityProperty); sp.ColumnName.SetRefName(_tableColumn); _endProperty.AddScalarProperty(sp); XmlModelHelper.NormalizeAndResolve(sp); if (_enforceConstraints) { var asm = _endProperty.Parent as AssociationSetMapping; Debug.Assert(asm != null, "_endProperty parent is not an AssociationSetMapping"); EnforceAssociationSetMappingRules.AddRule(cpc, asm); var assoc = asm.TypeName.Target; Debug.Assert(assoc != null, "_endProperty parent has a null Association"); if (assoc != null) { InferReferentialConstraints.AddRule(cpc, assoc); } } _created = sp; }
/// <summary> /// Merges and creates a list of all of the Properties. <ScalarProperty Name="LineNum" ColumnName="LineNum" /> /// </summary> /// <param name="endProperty">The EndProperty.</param> /// <param name="association">The association.</param> private void MergeScalarProperties(EndProperty endProperty, IAssociation association) { var properties = new List <ScalarProperty>(); foreach (var property in association.Properties) { var associationProperty = !association.Entity.Name.Equals(property.Property.Entity.Name) ? property.Property : property.ForeignProperty; var columnProperty = association.Entity.Name.Equals(property.Property.Entity.Name) ? property.Property : property.ForeignProperty; var prop = endProperty.ScalarProperties.Where(p => p.ColumnName.Equals(columnProperty.KeyName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (prop == null) { // The property doesn't exist so lets create it. prop = new ScalarProperty() { Name = associationProperty.Name }; } else if (!associationProperty.Name.Equals(prop.Name, StringComparison.OrdinalIgnoreCase)) // Column matches that in the database.. If the names are different, it wins. { // The propertyName has been updated. // TODO: Is there a better way to find out if they renamed the Property? //prop.Name = CodeSmith.SchemaHelper.Util.NamingConventions.PropertyName(prop.Name, false); } else { // Update the propertyName so it is always current with SchemaHelper. prop.Name = associationProperty.Name; } prop.ColumnName = columnProperty.KeyName; _mappingEntityPropertyNames[String.Format("{0}-{1}", associationProperty.Entity.Name, associationProperty.KeyName)] = prop.Name; properties.Add(prop); } endProperty.ScalarProperties = properties.Distinct().ToList(); }
internal static SortedListAllowDupes <AssociationPropertyIdentity> CreateIdentitiesFromAssociationEndProperty(EndProperty endProp) { var props = new SortedListAllowDupes <AssociationPropertyIdentity>(AssociationPropertyIdentityComparer.Instance); foreach (var sProp in endProp.ScalarProperties()) { var id = new AssociationPropertyIdentity(); var keyProperty = sProp.Name.Target as ConceptualProperty; id.PrincipalColumns = GetMappedColumnsForConceptualProperty(keyProperty); id.DependentColumns = new SortedListAllowDupes <DatabaseColumn>(new DatabaseColumnComparer()); var sSideProperty = sProp.ColumnName.Target; if (null != sSideProperty) { var stc = DatabaseColumn.CreateFromProperty(sSideProperty); id.DependentColumns.Add(stc); props.Add(id); } } return(props); }
internal static void ValidateEndProperty(EndProperty end) { ValidateEFElement(end); }
/// <summary> /// Creates a ScalarProperty in the given EndProperty. /// </summary> /// <param name="end">The EndProperty to place this ScalarProperty; cannot be null.</param> /// <param name="entityProperty">This must be a valid Property from the C-Model.</param> /// <param name="tableColumn">This must be a valid Property from the S-Model.</param> /// <returns></returns> internal CreateEndScalarPropertyCommand(EndProperty endProperty, Property entityProperty, Property tableColumn) : this(endProperty, entityProperty, tableColumn, true) { }
public void Invoke() { Debug.Assert(_association != null, "The Association reference is null"); // if the association was deleted in this transaction, just return since we won't need to process it if (_association == null || _association.XObject == null) { return; } // if foreign keys are supported in this EF version, then we skip all processing here. if (EdmFeatureManager.GetForeignKeysInModelFeatureState(_association.Artifact.SchemaVersion).IsEnabled()) { return; } Debug.Assert(_association.EntityModel.IsCSDL, "Inferring ref constraints isn't valid for SSDL associations"); Debug.Assert( _association.AssociationEnds().Count == 2, "The association to be processed does not have 2 ends while trying to infer ref constraints"); Debug.Assert( _association.AssociationSet != null, "The association being processed does not have a valid AssociationSet while trying to infer ref constraints"); // some local aliases for readability var end1 = _association.AssociationEnds()[0]; var end2 = _association.AssociationEnds()[1]; Debug.Assert(end1 != null && end2 != null, "Null end found while trying to infer ref constraints"); if (end1 == null || end2 == null) { return; } // regardless, we will remove the constraint if (_association.ReferentialConstraint != null) { DeleteEFElementCommand.DeleteInTransaction(_context, _association.ReferentialConstraint); } // we will never create a constraint against a self-association if (end1.Type.Target == end2.Type.Target) { return; } AssociationEnd principal = null; AssociationEnd dependent = null; ModelHelper.DeterminePrincipalDependentAssociationEnds( _association, out principal, out dependent, ModelHelper.DeterminePrincipalDependentAssociationEndsScenario.InferReferentialConstraint); // We found our principal and dependent ends but we still need to confirm that // the AssociationSetMapping contains key properties that are mapped to the same column if (principal != null && principal.Type.Target != null && dependent != null && dependent.Type.Target != null) { var associationSet = _association.AssociationSet; if (associationSet != null) { var asm = associationSet.AssociationSetMapping; if (asm != null && asm.EndProperties().Count == 2) { // any commonly mapped properties will be loaded into these HashSets var principalPropertyRefs = new HashSet <Property>(); var dependentPropertyRefs = new HashSet <Property>(); EndProperty dependentEndProperty = null; EndProperty principalEndProperty = null; var endProp1 = asm.EndProperties()[0]; var endProp2 = asm.EndProperties()[1]; if (endProp1.Name.Target != null) { if (endProp1.Name.Target.Role.Target == dependent) { dependentEndProperty = endProp1; principalEndProperty = endProp2; } else { dependentEndProperty = endProp2; principalEndProperty = endProp1; } } Debug.Assert( dependentEndProperty != null && principalEndProperty != null, "Either dependent or principal EndProperty is null"); if (dependentEndProperty != null && principalEndProperty != null) { // for each column that is mapped to a key property on the dependent end, determine if there is a // key property on the principal end that it is also mapped to. If there is, then we need a // ReferentialConstraint foreach (var dependentScalarProp in dependentEndProperty.ScalarProperties()) { var principalScalarProp = principalEndProperty.ScalarProperties() .FirstOrDefault(psp => psp.ColumnName.Target == dependentScalarProp.ColumnName.Target); if (principalScalarProp != null) { principalPropertyRefs.Add(principalScalarProp.Name.Target); dependentPropertyRefs.Add(dependentScalarProp.Name.Target); } } Debug.Assert( principalPropertyRefs.Count == dependentPropertyRefs.Count, "List of keys are mismatched while trying to create a Ref Constraint"); if (principalPropertyRefs.Count > 0 && dependentPropertyRefs.Count > 0 && principalPropertyRefs.Count == dependentPropertyRefs.Count) { // if the propertyRefs sets have any data in them, add the constraint var cmd = new CreateReferentialConstraintCommand( principal, dependent, principalPropertyRefs, dependentPropertyRefs); CommandProcessor.InvokeSingleCommand(_context, cmd); } } } } } }
public void Visit(EndProperty instruction) { }
internal void Build(CommandProcessorContext cpc) { var associationSet = AssociationSetEnd.Parent as AssociationSet; EndProperty endProperty = null; foreach (var val in AssociationSetEnd.EndProperties) { if (val.AssociationSetMapping == associationSet.AssociationSetMapping) { endProperty = val; break; } } // put all of entity keys in a list var keys = new List <Property>(); foreach (var property in ConceptualEntityType.ResolvableTopMostBaseType.Properties()) { if (property.IsKeyProperty) { keys.Add(property); } } // loop through all of the keys, adding view model elements for each foreach (var key in keys) { ScalarProperty existingScalarProperty = null; // for each column, see if we are already have a scalar property var antiDeps = key.GetAntiDependenciesOfType <ScalarProperty>(); foreach (var scalarProperty in antiDeps) { // if we find one, validate it if (scalarProperty != null && scalarProperty.Parent is EndProperty && scalarProperty.Name.Status == BindingStatus.Known && scalarProperty.Name.Target is Property && scalarProperty.Name.Target.Parent is EntityType) { // see if its already mapped by this type if (endProperty == scalarProperty.Parent) { // we are already mapping this existingScalarProperty = scalarProperty; break; } } } if (existingScalarProperty == null) { // we didn't find one BuildNew(cpc, key.LocalName.Value, key.DisplayName); } else if (existingScalarProperty != null && existingScalarProperty.Parent is EndProperty) { // we found an existing mapping BuildExisting(cpc, existingScalarProperty); } } }
public void Visit(EndProperty instruction) { _instructions.Add(instruction); }
internal AssociationEndIdentity(EndProperty endProp) { _propertyIdentities = AssociationPropertyIdentity.CreateIdentitiesFromAssociationEndProperty(endProp); }
private void DoBulkInsert(DbContext dbContext, object parent, string childPropertyName, IEnumerable <object> objectsToInsert) { Type entityClrType = objectsToInsert.First().GetType(); string entityName = entityClrType.Name; //Debug.Print(entityName); PropertyInfo entityKeyPropertyInfo = GetEntityKeyPropertyInfo(entityClrType); SqlCeCommand cmd = connection.CreateCommand(); cmd.CommandType = System.Data.CommandType.TableDirect; cmd.CommandText = GetTableName(entityName); SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable | ResultSetOptions.Scrollable); // Scalar Properties // AuotIncrement Property PropertyInfo auotIncrementPropInfo = null; Dictionary <PropertyInfo, int> ordinalMapping = null; if (scalarMappingCache.ContainsKey(entityName)) { ordinalMapping = scalarMappingCache[entityName].Item1; auotIncrementPropInfo = scalarMappingCache[entityName].Item2; } else { Dictionary <string, string> scalarMappingDictionary = edmx.GetScalarPropertiesMappingDictionary(entityName); Dictionary <string, string> revisedColumnMapping = RemoveAutoIncrementColumns(GetTableName(entityName), scalarMappingDictionary); ordinalMapping = GetAttributeToColumnOrdinalMapping(dbContext, entityClrType, rs, revisedColumnMapping); string auotIncrementPropertyName = scalarMappingDictionary.Keys.Except(revisedColumnMapping.Keys).SingleOrDefault(); if (!string.IsNullOrEmpty(auotIncrementPropertyName)) { auotIncrementPropInfo = entityClrType.GetProperty(auotIncrementPropertyName); } scalarMappingCache.Add(entityName, Tuple.Create(ordinalMapping, auotIncrementPropInfo)); } // Navigation Properties, Lookups if (!ordinalLookupMappingCache.ContainsKey(entityClrType)) { ordinalLookupMappingCache.Add(entityClrType, GetAttributeToColumnOrdinalMapping(dbContext, entityClrType, rs, edmx.GetLookupPropertiesMappingDictionary(entityClrType))); } Dictionary <PropertyInfo, int> ordinalLookupMapping = ordinalLookupMappingCache[entityClrType]; // Navigation Properties, Lists if (!listPropertiesCache.ContainsKey(entityClrType)) { listPropertiesCache.Add(entityClrType, edmx.GetListProperties(entityClrType)); } List <NavigationProperty> listNavigationProperties = listPropertiesCache[entityClrType]; // Parent PropertyInfo parentKeyPropertyInfo = null; int parentColumnOrdinal = 0; if (parent != null) { Type parentType = parent.GetType(); string parentEntityName = parentType.Name; string columnName = string.Empty; if (parentChildRelationCache.ContainsKey(Tuple.Create(parentEntityName, childPropertyName))) { parentKeyPropertyInfo = parentChildRelationCache[Tuple.Create(parentEntityName, childPropertyName)].Item1; columnName = parentChildRelationCache[Tuple.Create(parentEntityName, childPropertyName)].Item2; } else { EndProperty endProperty = edmx.GetParentChildRelationEndProperty(parentEntityName, childPropertyName); columnName = endProperty.ScalarProperties.Single().ColumnName; string parentEntityKeyPropertyName = edmx.GetEntityKeyPropertyName(parentEntityName); parentKeyPropertyInfo = parentType.GetProperty(parentEntityKeyPropertyName); parentChildRelationCache.Add(Tuple.Create(parentEntityName, childPropertyName), Tuple.Create(parentKeyPropertyInfo, columnName)); } SqlCeUpdatableRecord recParent = rs.CreateRecord(); parentColumnOrdinal = recParent.GetOrdinal(columnName); } foreach (var element in objectsToInsert) { if (IsObjectAlreadyInserted(element, entityKeyPropertyInfo)) { continue; } SqlCeUpdatableRecord rec = rs.CreateRecord(); // Scalar Properties foreach (var ordinalMappingEntry in ordinalMapping) { object value = ordinalMappingEntry.Key.GetValue(element, null); rec.SetValue(ordinalMappingEntry.Value, value); } // Navigation Properties, Lookups foreach (var ordinalLookupMappingEntry in ordinalLookupMapping) { object lookupInstance = ordinalLookupMappingEntry.Key.GetValue(element, null); if (lookupInstance != null) { DoBulkInsert(dbContext, null, string.Empty, new object[] { lookupInstance }); Type lookupType = ordinalLookupMappingEntry.Key.PropertyType; string lookupPropertyName = ordinalLookupMappingEntry.Key.Name; var dictKeyTuple = Tuple.Create(entityName, lookupPropertyName); if (!lookupMappingCache.ContainsKey(dictKeyTuple)) { string lookupKeyPropertyName = edmx.GetEntityKeyPropertyName(lookupType.Name); lookupMappingCache.Add(dictKeyTuple, Tuple.Create(ordinalLookupMappingEntry.Value, lookupType.GetProperty(lookupKeyPropertyName))); } int lookupOrdinal = lookupMappingCache[dictKeyTuple].Item1; object value = lookupMappingCache[dictKeyTuple].Item2.GetValue(lookupInstance, null); rec.SetValue(lookupOrdinal, value); } } if (parent != null) { rec.SetValue(parentColumnOrdinal, parentKeyPropertyInfo.GetValue(parent, null)); } rs.Insert(rec); if (auotIncrementPropInfo != null) { auotIncrementPropInfo.SetValue(element, int.Parse(commandIdentity.ExecuteScalar().ToString()), null); } // Navigation Properties, Lists foreach (NavigationProperty navigationProperty in listNavigationProperties) { object value = entityClrType.GetProperty(navigationProperty.Name).GetValue(element, null); if (value != null && value is ICollection) { IEnumerable <object> childList = (IEnumerable <object>)value; if (childList.Count() > 0) { DoBulkInsert(dbContext, element, navigationProperty.Name, childList); } } } } }