/// <summary> /// Helper method that raises the PropertyGenerated event /// </summary> /// <param name="eventArgs">The event arguments passed to the subscriber</param> internal void RaisePropertyGeneratedEvent(PropertyGeneratedEventArgs eventArgs) { if (this.OnPropertyGenerated != null) { this.OnPropertyGenerated(this, eventArgs); } }
/// <summary> /// Generate a navigation property /// </summary> /// <param name="target">the other end</param> /// <param name="referenceProperty">True to emit Reference navigation property</param> /// <returns>the generated property</returns> private CodeMemberProperty EmitNavigationProperty(RelationshipEndMember target) { CodeTypeReference typeRef = GetReturnType(target); // raise the PropertyGenerated event PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(Item, null, // no backing field typeRef); this.Generator.RaisePropertyGeneratedEvent(eventArgs); // [System.ComponentModel.Browsable(false)] // public TargetType TargetName // public EntityReference<TargetType> TargetName // or // public EntityCollection<targetType> TargetNames CodeMemberProperty property = new CodeMemberProperty(); // Only reference navigation properties are currently currently supported with XML serialization // and thus we should use the XmlIgnore and SoapIgnore attributes on other property types. AttributeEmitter.AddIgnoreAttributes(property); AttributeEmitter.AddBrowsableAttribute(property); AttributeEmitter.AddGeneratedCodeAttribute(property); CommentEmitter.EmitSummaryComments(Item, property.Comments); property.Name = Item.Name; if (eventArgs.ReturnType != null && !eventArgs.ReturnType.Equals(typeRef)) { property.Type = eventArgs.ReturnType; } else { property.Type = typeRef; } property.Attributes = MemberAttributes.Final; CodeExpression getMethod = EmitGetMethod(target); CodeExpression getReturnExpression; if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many) { property.Attributes |= AccessibilityFromGettersAndSetters(Item); // insert user-supplied Set code here, before the assignment // List<CodeStatement> additionalSetStatements = eventArgs.AdditionalSetStatements; if (additionalSetStatements != null && additionalSetStatements.Count > 0) { try { property.SetStatements.AddRange(additionalSetStatements.ToArray()); } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } CodeExpression valueRef = new CodePropertySetValueReferenceExpression(); if (typeRef != eventArgs.ReturnType) { // we need to cast to the actual type valueRef = new CodeCastExpression(typeRef, valueRef); } CodeExpression valueProperty = getMethod; // get // return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value; getReturnExpression = valueProperty; // set // ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value = value; property.SetStatements.Add( new CodeAssignStatement(valueProperty, valueRef)); // setup the accessibility of the navigation property setter and getter MemberAttributes propertyAccessibility = property.Attributes & MemberAttributes.AccessMask; PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name), PropertyEmitter.GetGetterAccessibility(Item), propertyAccessibility, true); PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name), PropertyEmitter.GetSetterAccessibility(Item), propertyAccessibility, false); List<CodeStatement> additionalAfterSetStatements = eventArgs.AdditionalAfterSetStatements; if (additionalAfterSetStatements != null && additionalAfterSetStatements.Count > 0) { try { property.SetStatements.AddRange(additionalAfterSetStatements.ToArray()); } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } } else { property.Attributes |= PropertyEmitter.GetGetterAccessibility(Item); // get // return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName"); getReturnExpression = getMethod; // set // if (value != null) ==> Only for non-binding scenario // { // this = // this.OnPropertyChanged("") // } CodeExpression valueRef = new CodePropertySetValueReferenceExpression(); CodeStatementCollection csc = null; if (this.Generator.UseDataServiceCollection == true) { csc = property.SetStatements; } else { CodeConditionStatement ccs = new CodeConditionStatement(EmitExpressionDoesNotEqualNull(valueRef)); property.SetStatements.Add(ccs); csc = ccs.TrueStatements; } csc.Add(new CodeAssignStatement(getMethod, valueRef)); if (eventArgs.AdditionalAfterSetStatements != null) { try { foreach (CodeStatement s in eventArgs.AdditionalAfterSetStatements) { csc.Add(s); } } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } } // if additional Get statements were specified by the event subscriber, insert them now // List<CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements; if (additionalGetStatements != null && additionalGetStatements.Count > 0) { try { property.GetStatements.AddRange(additionalGetStatements.ToArray()); } catch (ArgumentNullException ex) { Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty, EdmSchemaErrorSeverity.Error, ex); } } property.GetStatements.Add(new CodeMethodReturnStatement(getReturnExpression)); return property; }
private CodeMemberProperty CreateEntitySetProperty(EntitySet set) { Debug.Assert(set != null, "Property is Null"); // trying to get // // [System.ComponentModel.Browsable(false)] // public ObjectQuery<Customer> Customers // { // get // { // if ((this._Customers == null)) // { // this._Customers = base.CreateQuery<Customer>("[Customers]"); // } // return this._Customers; // } // } CodeMemberProperty codeProperty = new CodeMemberProperty(); codeProperty.Attributes = MemberAttributes.Final | GetEntitySetPropertyAccessibility(set); codeProperty.Name = set.Name; codeProperty.HasGet = true; codeProperty.HasSet = false; // SQLBUDT 598300: property to get query hides a property on base Context? if (null != TypeReference.ObjectContextBaseClassType.GetProperty(set.Name)) { codeProperty.Attributes |= MemberAttributes.New; } AttributeEmitter.AddBrowsableAttribute(codeProperty); AttributeEmitter.AddGeneratedCodeAttribute(codeProperty); CodeTypeReference genericParameter = Generator.GetLeastPossibleQualifiedTypeReference(set.ElementType); codeProperty.Type = TypeReference.AdoFrameworkGenericClass("DataServiceQuery", genericParameter); string fieldName = Utils.FieldNameFromPropName(set.Name); // raise the PropertyGenerated event before proceeding further PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(set, fieldName, codeProperty.Type); Generator.RaisePropertyGeneratedEvent(eventArgs); if (eventArgs.ReturnType == null || !eventArgs.ReturnType.Equals(codeProperty.Type)) { throw EDesignUtil.InvalidOperation(Strings.CannotChangePropertyReturnType(set.Name, Item.Name)); } List<CodeAttributeDeclaration> additionalAttributes = eventArgs.AdditionalAttributes; if (additionalAttributes != null && additionalAttributes.Count > 0) { try { codeProperty.CustomAttributes.AddRange(additionalAttributes.ToArray()); } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } // we need to insert user-specified code before other/existing code, including // the return statement List<CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements; if (additionalGetStatements != null && additionalGetStatements.Count > 0) { try { codeProperty.GetStatements.AddRange(additionalGetStatements.ToArray()); } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } codeProperty.GetStatements.Add( new CodeConditionStatement( EmitExpressionEqualsNull(new CodeFieldReferenceExpression(ThisRef, fieldName)), new CodeAssignStatement( new CodeFieldReferenceExpression(ThisRef, fieldName), new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeBaseReferenceExpression(), "CreateQuery", new CodeTypeReference[] { genericParameter } ), new CodePrimitiveExpression(set.Name) ) ) ) ); codeProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( ThisRef, fieldName ) ) ); // property summary CommentEmitter.EmitSummaryComments(set, codeProperty.Comments); return codeProperty; }