Ejemplo n.º 1
0
        public void Ctor(bool value)
        {
            var attribute = new EditableAttribute(value);

            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(value, attribute.AllowInitialValue);
        }
Ejemplo n.º 2
0
        public void Can_construct_and_both_AllowEdit_and_AllowInitialValue_are_set(bool value)
        {
            var attribute = new EditableAttribute(value);

            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(value, attribute.AllowInitialValue);
        }
Ejemplo n.º 3
0
        public void Properties_are_independent(bool value)
        {
            var attribute = new EditableAttribute(value);
            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(value, attribute.AllowInitialValue);

            attribute.AllowInitialValue = !value;
            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(!value, attribute.AllowInitialValue);
        }
        public void Properties_ChangingOneProperty_DoesNotAffectTheOther(bool value)
        {
            var attribute = new EditableAttribute(value);
            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(value, attribute.AllowInitialValue);

            attribute.AllowInitialValue = !value;
            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(!value, attribute.AllowInitialValue);
        }
Ejemplo n.º 5
0
        public void Properties_ChangingOneProperty_DoesNotAffectTheOther(bool value)
        {
            var attribute = new EditableAttribute(value);

            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(value, attribute.AllowInitialValue);

            attribute.AllowInitialValue = !value;
            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(!value, attribute.AllowInitialValue);
        }
Ejemplo n.º 6
0
        public void Properties_are_independent(bool value)
        {
            var attribute = new EditableAttribute(value);

            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(value, attribute.AllowInitialValue);

            attribute.AllowInitialValue = !value;
            Assert.Equal(value, attribute.AllowEdit);
            Assert.Equal(!value, attribute.AllowInitialValue);
        }
        protected override IEnumerable<Attribute> GetMemberAttributes(PropertyDescriptor pd)
        {
            List<Attribute> attributes = new List<Attribute>();

            // Exclude any EntityState, EntityReference, etc. members
            if (ShouldExcludeEntityMember(pd))
            {
                // for these members, we don't want to do any attribute inference
                return attributes.ToArray();
            }

            EditableAttribute editableAttribute = null;
            bool inferRoundtripOriginalAttribute = false;

            bool hasKeyAttribute = (pd.Attributes[typeof(KeyAttribute)] != null);
            bool isEntity = EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
            if (isEntity)
            {
                EntityType entityType = (EntityType)EdmType;
                EdmMember keyMember = entityType.KeyMembers.SingleOrDefault(k => k.Name == pd.Name);
                if (keyMember != null && !hasKeyAttribute)
                {
                    attributes.Add(new KeyAttribute());
                    hasKeyAttribute = true;
                }
            }

            EdmProperty member = EdmType.Members.SingleOrDefault(p => p.Name == pd.Name) as EdmProperty;
            if (member != null)
            {
                if (hasKeyAttribute)
                {
                    // key members must always be roundtripped
                    inferRoundtripOriginalAttribute = true;

                    // key members that aren't also FK members are non-editable (but allow an initial value)
                    if (!_keyIsEditable)
                    {
                        editableAttribute = new EditableAttribute(false) { AllowInitialValue = true };
                    }
                }

                // Check if the member is DB generated and add the DatabaseGeneratedAttribute to it if not already present.                
                if (pd.Attributes[typeof(DatabaseGeneratedAttribute)] == null)
                {
                    MetadataProperty md = ObjectContextUtilities.GetStoreGeneratedPattern(member);
                    if (md != null)
                    {
                        if ((string)md.Value == "Computed")
                        {
                            attributes.Add(new DatabaseGeneratedAttribute(DatabaseGeneratedOption.Computed));
                        }
                        else if ((string)md.Value == "Identity")
                        {
                            attributes.Add(new DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity));
                        }
                    }
                }

                // Add implicit ConcurrencyCheck attribute to metadata if ConcurrencyMode is anything other than ConcurrencyMode.None
                Facet facet = member.TypeUsage.Facets.SingleOrDefault(p => p.Name == "ConcurrencyMode");
                if (facet != null && facet.Value != null && (ConcurrencyMode)facet.Value != ConcurrencyMode.None &&
                    pd.Attributes[typeof(ConcurrencyCheckAttribute)] == null)
                {
                    attributes.Add(new ConcurrencyCheckAttribute());
                    inferRoundtripOriginalAttribute = true;
                }

                bool isStringType = pd.PropertyType == typeof(string) || pd.PropertyType == typeof(char[]);

                // Add Required attribute to metdata if the member cannot be null and it is either a reference type or a Nullable<T>
                if (!member.Nullable && (!pd.PropertyType.IsValueType || IsNullableType(pd.PropertyType)) &&
                    pd.Attributes[typeof(RequiredAttribute)] == null)
                {
                    attributes.Add(new RequiredAttribute());
                }

                if (isStringType &&
                    pd.Attributes[typeof(StringLengthAttribute)] == null)
                {
                    facet = member.TypeUsage.Facets.SingleOrDefault(p => p.Name == "MaxLength");
                    if (facet != null && facet.Value != null && facet.Value.GetType() == typeof(int))
                    {
                        // need to test for Type int, since the value can also be of type
                        // System.Data.Metadata.Edm.EdmConstants.Unbounded
                        int maxLength = (int)facet.Value;
                        attributes.Add(new StringLengthAttribute(maxLength));
                    }
                }

                bool hasTimestampAttribute = (pd.Attributes[typeof(TimestampAttribute)] != null);

                if (_timestampMember == member && !hasTimestampAttribute)
                {
                    attributes.Add(new TimestampAttribute());
                    hasTimestampAttribute = true;
                }

                // All members marked with TimestampAttribute (inferred or explicit) need to
                // have [Editable(false)] and [RoundtripOriginal] applied
                if (hasTimestampAttribute)
                {
                    inferRoundtripOriginalAttribute = true;

                    if (editableAttribute == null)
                    {
                        editableAttribute = new EditableAttribute(false);
                    }
                }

                // Add RTO to this member if required. If this type has a timestamp
                // member that member should be the ONLY member we apply RTO to.
                // Dont apply RTO if it is an association member.
                bool isForeignKeyMember = _foreignKeyMembers != null && _foreignKeyMembers.Contains(member);
                if ((_timestampMember == null || _timestampMember == member) &&
                    (inferRoundtripOriginalAttribute || isForeignKeyMember) &&
                    pd.Attributes[typeof(AssociationAttribute)] == null)
                {
                    if (pd.Attributes[typeof(RoundtripOriginalAttribute)] == null)
                    {
                        attributes.Add(new RoundtripOriginalAttribute());
                    }
                }
            }

            // Add the Editable attribute if required
            if (editableAttribute != null && pd.Attributes[typeof(EditableAttribute)] == null)
            {
                attributes.Add(editableAttribute);
            }

            if (isEntity)
            {
                AddAssociationAttributes(pd, attributes);
            }

            return attributes.ToArray();
        }
        /// <summary>
        /// Returns a collection of all the <see cref="Attribute"/>s we infer from the metadata associated
        /// with the metadata member corresponding to the given property descriptor
        /// </summary>
        /// <param name="pd">A <see cref="PropertyDescriptor"/>.</param>
        /// <returns>A collection of attributes inferred from metadata in the given descriptor.</returns>
        protected override IEnumerable<Attribute> GetMemberAttributes(PropertyDescriptor pd)
        {
            List<Attribute> attributes = new List<Attribute>();
            MetaDataMember member = this._metaType.DataMembers.Where(p => p.Name == pd.Name).SingleOrDefault();
            if (member != null)
            {
                EditableAttribute editableAttribute = null;
                bool hasKeyAttribute = (pd.Attributes[typeof(KeyAttribute)] != null);
                if (member.IsPrimaryKey && !hasKeyAttribute)
                {
                    attributes.Add(new KeyAttribute());
                    hasKeyAttribute = true;
                }

                // Check if the member is DB generated and add the DatabaseGeneratedAttribute to it if not already present.
                if (member.IsDbGenerated && pd.Attributes[typeof(DatabaseGeneratedAttribute)] == null)
                {
                    if (member.AutoSync == AutoSync.OnInsert)
                    {
                        attributes.Add(new DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity));
                    }
                    else if (member.AutoSync == AutoSync.Always)
                    {
                        attributes.Add(new DatabaseGeneratedAttribute(DatabaseGeneratedOption.Computed));
                    }
                }

                if (hasKeyAttribute && !this._keyIsEditable)
                {
                    editableAttribute = new EditableAttribute(false) { AllowInitialValue = true };
                }

                if (member.IsAssociation &&
                    pd.Attributes[typeof(System.ComponentModel.DataAnnotations.AssociationAttribute)] == null)
                {
                    System.ComponentModel.DataAnnotations.AssociationAttribute assocAttrib = this.TypeDescriptionContext.CreateAssociationAttribute(member);
                    attributes.Add(assocAttrib);
                }

                // Add Required attribute to metdata if the member cannot be null and it is either a reference type or a Nullable<T>
                bool isStringType = pd.PropertyType == typeof(string) || pd.PropertyType == typeof(char[]);
                if (!member.CanBeNull && (!pd.PropertyType.IsValueType || IsNullableType(pd.PropertyType)) &&
                    pd.Attributes[typeof(RequiredAttribute)] == null)
                {
                    attributes.Add(new RequiredAttribute());
                }

                // Add implicit ConcurrencyCheck attribute to metadata if UpdateCheck is anything other than UpdateCheck.Never
                if (member.UpdateCheck != UpdateCheck.Never &&
                    pd.Attributes[typeof(ConcurrencyCheckAttribute)] == null)
                {
                    attributes.Add(new ConcurrencyCheckAttribute());
                }

                bool hasTimestampAttribute = (pd.Attributes[typeof(TimestampAttribute)] != null);
                if (member.IsVersion && !hasTimestampAttribute)
                {
                    attributes.Add(new TimestampAttribute());
                    hasTimestampAttribute = true;
                }

                // All members marked with TimestampAttribute (inferred or explicit) need to
                // have [Editable(false)] applied
                if (hasTimestampAttribute && editableAttribute == null)
                {
                    editableAttribute = new EditableAttribute(false);
                }

                // Add RoundtripOriginal attribute to this member unless
                // - this entity has a timestamp member, in which case that member should be the ONLY
                //   member we apply RTO to.
                // - the member is marked with AssociationAttribute
                if (!member.IsAssociation && 
                    pd.Attributes[typeof(System.ComponentModel.DataAnnotations.AssociationAttribute)] == null
                    && (this._metaType.VersionMember == null || member.IsVersion))
                {
                    if (pd.Attributes[typeof(RoundtripOriginalAttribute)] == null)
                    {
                        attributes.Add(new RoundtripOriginalAttribute());
                    }
                }

                if (isStringType && member.DbType != null && member.DbType.Length > 0 &&
                    pd.Attributes[typeof(StringLengthAttribute)] == null)
                {
                    InferStringLengthAttribute(member.DbType, attributes);
                }

                // Add EditableAttribute if required
                if (editableAttribute != null && pd.Attributes[typeof(EditableAttribute)] == null)
                {
                    attributes.Add(editableAttribute);
                }
            }
            return attributes.ToArray();
        }
        public void GetBindingMetadata_EditableAttributeTrue_SetsReadOnlyFalse()
        {
            // Arrange
            var provider = new DataAnnotationsMetadataProvider();

            var editable = new EditableAttribute(allowEdit: true);

            var attributes = new Attribute[] { editable };
            var key = ModelMetadataIdentity.ForType(typeof(string));
            var context = new BindingMetadataProviderContext(key, new ModelAttributes(attributes));

            // Act
            provider.GetBindingMetadata(context);

            // Assert
            Assert.False(context.BindingMetadata.IsReadOnly);
        }
Ejemplo n.º 10
0
 public void Can_construct_and_both_AllowEdit_and_AllowInitialValue_are_set(bool value)
 {
     var attribute = new EditableAttribute(value);
     Assert.Equal(value, attribute.AllowEdit);
     Assert.Equal(value, attribute.AllowInitialValue);
 }
 public void Ctor(bool value)
 {
     var attribute = new EditableAttribute(value);
     Assert.Equal(value, attribute.AllowEdit);
     Assert.Equal(value, attribute.AllowInitialValue);
 }
        protected virtual IEnumerable<Attribute> GetEntityMemberAttributes(PropertyDescriptor propertyDescriptor)
        {
            if (_classMetadata == null)
                return null;
            var attributes = new List<Attribute>();

            //KeyAttributes
            if (_classMetadata.Identifier != null)
            {
                foreach (Column id in _identifierCols)
                {
                    if (id.Name == propertyDescriptor.Name)
                    {
                        if (propertyDescriptor.Attributes[typeof(KeyAttribute)] == null)
                        {
                            attributes.Add(new KeyAttribute());
                        }
                        if (propertyDescriptor.Attributes[typeof(EditableAttribute)] == null)
                        {
                            //An identifier is not editable, sometimes anyway it allow an initial value
                            var editable = new EditableAttribute(false);
                            if (id.Value is SimpleValue)
                                editable.AllowInitialValue =
                                    "assigned".Equals(((SimpleValue)id.Value).IdentifierGeneratorStrategy,
                                                      StringComparison.InvariantCultureIgnoreCase);
                            attributes.Add(editable);
                        }
                        break;
                    }
                }
            }
            Property member = _classMetadata.PropertyIterator.FirstOrDefault(x => x.Name == propertyDescriptor.Name);
            if (member == null)             //If ther's no mapping in nhibernate... 
                return attributes;
            //Required
            if ((!member.IsNullable) &&
                (propertyDescriptor.PropertyType.IsValueType &&
                 (propertyDescriptor.Attributes[typeof(RequiredAttribute)] == null)))
            {

                attributes.Add(new RequiredAttribute());
            }
            //Association
            if (member.Type.IsAssociationType &&
                (propertyDescriptor.Attributes[typeof(AssociationAttribute)] == null))
            {
                string name;
                string thisKey = "";
                string otherkey = "";
                if (member.Type.IsCollectionType)
                {
                    name = propertyDescriptor.ComponentType.FullName + "_" + member.Name;

                    if (member.Type.ReturnedClass.GetGenericArguments().Length != 1)
                    {
                        throw new Exception(
                            String.Format(
                                "The property {0} is not a generic collection as expected (like IList<T>)...",
                                member.Name));
                    }
                    Type targetClassType = member.Type.ReturnedClass.GetGenericArguments()[0];

                    foreach (Column col in _identifierCols)
                    {
                        thisKey += (thisKey != "" ? ", " : "") + col.Name;

                        //*****Naming convention****
                        //Here I'm assuming that the name of each field in the type that holds the foreign key observe
                        //the following structure: 

                        string field = member.Name.Replace(Inflector.Pluralize(targetClassType.Name), "") +
                            propertyDescriptor.ComponentType.Name + "_" + col.Name;

                        otherkey += (otherkey != "" ? ", " : "") + field;

                        if (targetClassType.GetProperties(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault(x => x.Name == field) == null)
                            throw new Exception(String.Format("The class {0} doesn't contain a Property named {1}",
                                                targetClassType.Name, field));
                    }

                }
                else //Member is a class type
                {
                    //Key could be composite, cycle every identifier on "the other side"
                    PersistentClass otherMappingClass = _nhibernateConfiguration.GetClassMapping(member.Type.ReturnedClass);
                    foreach (Column col in otherMappingClass.Key.ColumnIterator)
                    {
                        //Naming Convention:
                        //The name of each foreign key field be MUST BE the name of the class field + "_" + the name of the key field in the targetclass
                        thisKey += (thisKey != "" ? ", " : "") + member.Name + "_" + col.Name;
                        otherkey += (otherkey != "" ? ", " : "") + col.Name;
                    }

                    //Check: this name MUST ALWAYS BE the same on the both side of a bi-directional association
                    name = member.Type.ReturnedClass.FullName
                        + "_" + Inflector.Pluralize(member.PersistentClass.NodeName);
                }

                //CHECK: When do you want to add an IncludeAttribute ?
                if (!_classMetadata.IsLazy)
                {
                    var incAttr = new IncludeAttribute();
                    attributes.Add(incAttr);
                }

                var attribute = new AssociationAttribute(
                    name,
                    thisKey,
                    otherkey
                    );
                Type fromParent = ForeignKeyDirection.ForeignKeyFromParent.GetType();
                attribute.IsForeignKey =
                    fromParent.IsInstanceOfType(((IAssociationType)member.Type).ForeignKeyDirection);
                attributes.Add(attribute);
            }
            //RoundtripOriginal
            if (member == _classMetadata.Version)
                attributes.Add(new RoundtripOriginalAttribute());
            return attributes.ToArray();
        }