Exemple #1
0
        private MetaDataProperty CreateDataProperty(IProperty p)
        {
            var dp = new MetaDataProperty();

            dp.NameOnServer     = p.Name;
            dp.IsNullable       = p.IsNullable;
            dp.IsPartOfKey      = p.IsPrimaryKey() ? true : (bool?)null;
            dp.IsIdentityColumn = p.IsPrimaryKey() && p.ValueGenerated == ValueGenerated.OnAdd;
            dp.MaxLength        = p.GetMaxLength();
            dp.DataType         = NormalizeDataTypeName(p.ClrType);
            dp.ConcurrencyMode  = p.IsConcurrencyToken ? "Fixed" : null;
            var dfa = p.GetAnnotations().Where(a => a.Name == "DefaultValue").FirstOrDefault();

            if (dfa != null)
            {
                dp.DefaultValue = dfa.Value;
            }
            else if (!p.IsNullable)
            {
                // TODO: this should really be done on the client.
                if (p.ClrType == typeof(TimeSpan))
                {
                    dp.DefaultValue = "PT0S";
                }
                // dp.DefaultValue = // get default value for p.ClrType datatype
            }
            dp.AddValidators(p.ClrType);
            return(dp);
        }
Exemple #2
0
        /// <summary>
        /// Gets the strongly typed value of the metadata property with the given name and culture.
        /// </summary>
        /// <typeparam name="T">Type of the value to retrieve.</typeparam>
        /// <param name="name">Name of the property to retrieve the value for.</param>
        /// <returns>A metadata property value.</returns>
        public virtual T GetValue <T>(string name)
        {
            MetaDataProperty property = GetProperty(name, true);

            return(property == null
                       ? default(T)
                       : ObjectBuilder.BuildObjectValue(property.Value, default(T)));
        }
Exemple #3
0
        /// <summary>
        /// Adds a complex type definition
        /// </summary>
        /// <param name="compType">The complex type</param>
        /// <param name="columnNames">The names of the columns which the complex type spans.</param>
        /// <returns>The class name and namespace of the complex type, in the form "Location:#Breeze.Nhibernate.NorthwindIBModel"</returns>
        string AddComponent(ComponentType compType, string[] columnNames)
        {
            var type = compType.ReturnedClass;

            // "Location:#Breeze.Nhibernate.NorthwindIBModel"
            var classKey = type.Name + ":#" + type.Namespace;

            if (_typeNames.Contains(classKey))
            {
                // Only add a complex type definition once.
                return(classKey);
            }

            var cmap = new MetaType();

            _typeList.Insert(0, cmap);
            _typeNames.Add(classKey);

            cmap.ShortName     = type.Name;
            cmap.Namespace     = type.Namespace;
            cmap.IsComplexType = true;

            cmap.DataProperties = new List <MetaDataProperty>();

            var propNames = compType.PropertyNames;
            var propTypes = compType.Subtypes;
            var propNull  = compType.PropertyNullability;

            var colIndex = 0;

            for (int i = 0; i < propNames.Length; i++)
            {
                var propType = propTypes[i];
                var propName = propNames[i];
                if (propType.IsComponentType)
                {
                    // nested complex type
                    var compType2       = (ComponentType)propType;
                    var span            = compType2.GetColumnSpan((IMapping)_sessionFactory);
                    var subColumns      = columnNames.Skip(colIndex).Take(span).ToArray();
                    var complexTypeName = AddComponent(compType2, subColumns);
                    var compMap         = new MetaDataProperty();
                    compMap.NameOnServer    = propName;
                    compMap.ComplexTypeName = complexTypeName;
                    compMap.IsNullable      = propNull[i];
                    cmap.DataProperties.Add(compMap);
                    colIndex += span;
                }
                else
                {
                    // data property
                    var dmap = MakeDataProperty(propName, propType, propNull[i], false, false);
                    cmap.DataProperties.Add(dmap);
                    colIndex++;
                }
            }
            return(classKey);
        }
Exemple #4
0
        private MetaType CreateMetaType(Microsoft.EntityFrameworkCore.Metadata.IEntityType et, Dictionary <Type, String> dbSetMap)
        {
            var mt = new MetaType {
                ShortName = et.ClrType.Name,
                Namespace = et.ClrType.Namespace
            };

            if (et.IsOwned())
            {
                mt.IsComplexType = true;
            }
            if (dbSetMap.TryGetValue(et.ClrType, out string resourceName))
            {
                mt.DefaultResourceName = resourceName;
            }
            var baseType = et.BaseType;

            if (baseType != null)
            {
                mt.BaseTypeName = baseType.ClrType.Name + ":#" + baseType.ClrType.Namespace;
            }

            // exclude base class properties
            mt.DataProperties = et.GetProperties().Where(p => p.DeclaringType.ClrType.Equals(et.ClrType)).Select(p => CreateDataProperty(p)).ToList();


            // EF returns parent's key with the complex type - we need to remove this.
            if (mt.IsComplexType)
            {
                mt.DataProperties = mt.DataProperties.Where(dp => dp.IsPartOfKey == null).ToList();
            }

            if (!mt.IsComplexType)
            {
                mt.AutoGeneratedKeyType = mt.DataProperties.Any(dp => dp.IsIdentityColumn) ? AutoGeneratedKeyType.Identity : AutoGeneratedKeyType.None;
            }

            // Handle complex properties
            // for now this only complex types ( 'owned types' in EF parlance are eager loaded)
            var ownedNavigations = et.GetNavigations().Where(n => n.GetTargetType().IsOwned());

            ownedNavigations.ToList().ForEach(n => {
                var complexType    = n.GetTargetType().ClrType;
                var dp             = new MetaDataProperty();
                dp.NameOnServer    = n.Name;
                dp.IsNullable      = false;
                dp.IsPartOfKey     = false;
                dp.ComplexTypeName = NormalizeTypeName(complexType);
                mt.DataProperties.Add(dp);
            });

            mt.NavigationProperties = et.GetNavigations()
                                      .Where(n => !n.GetTargetType().IsOwned() && n.DeclaringType.ClrType.Equals(et.ClrType)).Select(p => CreateNavProperty(p)).ToList();

            return(mt);
        }
Exemple #5
0
        /// <summary>
        /// Make data property metadata for the entity
        /// </summary>
        /// <param name="propName">name of the property on the server</param>
        /// <param name="type">data type of the property, e.g. Int32</param>
        /// <param name="isNullable">whether the property is nullable in the database</param>
        /// <param name="isKey">true if this property is part of the key for the entity</param>
        /// <param name="isVersion">true if this property contains the version of the entity (for a concurrency strategy)</param>
        /// <returns></returns>
        private MetaDataProperty MakeDataProperty(string propName, IType type, bool isNullable, bool isKey, bool isVersion)
        {
            string newType;
            var    typeName = (BreezeTypeMap.TryGetValue(type.Name, out newType)) ? newType : type.Name;

            var dmap = new MetaDataProperty {
                NameOnServer = propName,
                DataType     = typeName,
                IsNullable   = isNullable
            };


            var sqlTypes = type.SqlTypes((ISessionFactoryImplementor)this._sessionFactory);
            var sqlType  = sqlTypes[0];

            // This doesn't work; NH does not pick up the default values from the property/column definition
            //if (type is PrimitiveType && !(type is DateTimeOffsetType))
            //{
            //    var def = ((PrimitiveType)type).DefaultValue;
            //    if (def != null && def.ToString() != "0")
            //        dmap.Add("defaultValue", def);
            //}

            if (isKey)
            {
                dmap.IsPartOfKey = true;
            }
            if (isVersion)
            {
                dmap.ConcurrencyMode = "Fixed";
            }

            if (!isNullable)
            {
                dmap.Validators.Add(MetaValidator.Required);
            }
            if (sqlType.LengthDefined)
            {
                dmap.MaxLength = sqlType.Length;
                dmap.Validators.Add(new MaxLengthMetaValidator(sqlType.Length));
            }

            var validator = MetaValidator.FindValidator(type.ReturnedClass);

            if (validator != null)
            {
                dmap.Validators.Add(validator);
            }

            return(dmap);
        }
        private BreezeMetadata GetMetadataFromContext(DbContext dbContext)
        {
            var metadata = new BreezeMetadata();

            metadata.StructuralTypes = dbContext.Model.GetEntityTypes().Select(et => {
                var mt = new MetaType();
                metadata.StructuralTypes.Add(mt);
                mt.ShortName = et.Name;
                mt.Namespace = et.ClrType.Namespace;

                mt.DataProperties = et.GetProperties().Select(p => {
                    var dp = new MetaDataProperty();

                    dp.NameOnServer    = p.Name;
                    dp.IsNullable      = p.IsNullable;
                    dp.IsPartOfKey     = p.IsPrimaryKey();
                    dp.MaxLength       = p.GetMaxLength();
                    dp.DataType        = p.ClrType.ToString();
                    dp.ConcurrencyMode = p.IsConcurrencyToken ? "None" : "Identity";
                    var dfa            = p.GetAnnotations().Where(a => a.Name == "DefaultValue").FirstOrDefault();
                    if (dfa != null)
                    {
                        dp.DefaultValue = dfa.Value;
                    }
                    return(dp);
                }).ToList();
                mt.NavigationProperties = et.GetNavigations().Select(p => {
                    var np            = new MetaNavProperty();
                    np.NameOnServer   = p.Name;
                    np.EntityTypeName = p.GetTargetType().Name;
                    np.IsScalar       = !p.IsCollection();
                    // FK_<dependent type name>_<principal type name>_<foreign key property name>
                    np.AssociationName = BuildAssocName(p);
                    if (p.IsDependentToPrincipal())
                    {
                        np.AssociationName         = BuildAssocName(p);
                        np.ForeignKeyNamesOnServer = p.ForeignKey.Properties.Select(fkp => fkp.Name).ToList();
                    }
                    else
                    {
                        np.AssociationName            = BuildAssocName(p.FindInverse());
                        np.InvForeignKeyNamesOnServer = p.ForeignKey.Properties.Select(fkp => fkp.Name).ToList();
                    }

                    return(np);
                }).ToList();
                return(mt);
            }).ToList();
            return(metadata);
        }
Exemple #7
0
        private MetaDataProperty GetProperty(string name, bool ensureExist)
        {
            MetaDataProperty property =
                Properties.FirstOrDefault(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase));

            if (property == null && ensureExist)
            {
                property = new MetaDataProperty {
                    Name = name
                };
                Properties.Add(property);
            }

            return(property);
        }
Exemple #8
0
        /// <summary>
        /// Sets the value of the given metadata property.
        /// </summary>
        /// <typeparam name="T">Type of the value to set.</typeparam>
        /// <param name="name">Name of the metadata property to set.</param>
        /// <param name="value">New property value.</param>
        public virtual void SetValue <T>(string name, T value)
        {
            MetaDataProperty property = GetProperty(name, true);
            object           oldValue = property.Value;
            var newValue = ObjectBuilder.BuildObjectValue <T>(value);

            property.Value = newValue;

            // ReSharper disable CompareNonConstrainedGenericWithNull
            bool changed = oldValue == null
                               ? newValue != null
                               : !oldValue.Equals(newValue);

            // ReSharper restore CompareNonConstrainedGenericWithNull

            IsChanged = IsChanged || changed;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="document"></param>
        /// <param name="store"></param>
        /// <param name="index"></param>
        /// <param name="boost"></param>
        /// <exception cref="Exception"></exception>
        public void Set(
            string name, object value, Document document, Field.Store store, Field.Index index, float?boost)
        {
            var metaData = value as MetaData;

            if (metaData == null)
            {
                throw new Exception(
                          "MetaDataFieldBridge can only be used for properties of type MetaData.");
            }

            foreach (MetaDataPropertyDefinition property in metaData.GetPropertyDefinitions())
            {
                if (!property.Indexed)
                {
                    continue;
                }
                string propertyName = property.Name.ToLowerInvariant();

                if (!property.IsLocalized)
                {
                    MetaDataProperty item =
                        metaData.Properties.FirstOrDefault(x => x.Name.ToLowerInvariant() == propertyName);
                    if (item == null)
                    {
                        continue;
                    }

                    AddField(
                        document, item.FullName, GetPropertyValue(item), property.IsAnalyzed, property.IsStored, boost);
                }
                else
                {
                    IEnumerable <MetaDataProperty> items =
                        metaData.Properties.Where(x => x.Name.ToLowerInvariant() == propertyName);

                    foreach (MetaDataProperty item in items)
                    {
                        AddField(document, item.FullName, GetPropertyValue(item), property.IsAnalyzed,
                                 property.IsStored, boost);
                    }
                }
            }
        }
Exemple #10
0
        private MetaDataProperty GetProperty(string name)
        {
            var property = Properties.FirstOrDefault(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase));

            // HACK: Preserves backward compatibility with old databases,
            // and forces non-localized properties to have invariant culture id (0).
            if (property != null && property.CultureID != CultureInfo.InvariantCulture.LCID)
            {
                property.CultureID = CultureInfo.InvariantCulture.LCID;
            }

            if (property == null)
            {
                property = new MetaDataProperty {
                    CultureID = CultureInfo.InvariantCulture.LCID, Name = name
                };
                Properties.Add(property);
            }

            return(property);
        }
 private static string GetPropertyValue(MetaDataProperty property)
 {
     return(property == null || property.Value == null ? String.Empty : property.Value.ToString());
 }
Exemple #12
0
        /// <summary>
        /// Add the properties for an entity.
        /// </summary>
        /// <param name="meta"></param>
        /// <param name="dataList">will be populated with the data properties of the entity</param>
        /// <param name="navList">will be populated with the navigation properties of the entity</param>
        void AddClassProperties(IClassMetadata meta, List <MetaDataProperty> dataList, List <MetaNavProperty> navList)
        {
            var persister = meta as AbstractEntityPersister;
            var metaModel = persister.EntityMetamodel;
            var type      = metaModel.Type;

            HashSet <String> inheritedProperties = GetSuperProperties(persister);

            var propNames  = meta.PropertyNames;
            var propTypes  = meta.PropertyTypes;
            var propNull   = meta.PropertyNullability;
            var properties = metaModel.Properties;

            for (int i = 0; i < propNames.Length; i++)
            {
                var propName = propNames[i];
                if (inheritedProperties.Contains(propName))
                {
                    continue;                                  // skip property defined on superclass
                }
                var propType = propTypes[i];
                if (!propType.IsAssociationType) // skip association types until we handle all the data types, so they can be looked up
                {
                    if (propType.IsComponentType)
                    {
                        // complex type
                        var columnNames     = persister.GetPropertyColumnNames(i);
                        var compType        = (ComponentType)propType;
                        var complexTypeName = AddComponent(compType, columnNames);
                        var comp            = new MetaDataProperty {
                            NameOnServer    = propName,
                            ComplexTypeName = complexTypeName,
                            IsNullable      = propNull[i]
                        };
                        dataList.Add(comp);
                    }
                    else
                    {
                        // data property
                        var isKey     = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i);
                        var isVersion = meta.IsVersioned && i == meta.VersionProperty;

                        var dmap = MakeDataProperty(propName, propType, propNull[i], isKey, isVersion);
                        dataList.Add(dmap);
                    }
                }

                // Expose enum types
                if (propType is AbstractEnumType)
                {
                    var types = propType.GetType().GetGenericArguments();
                    if (types.Length > 0)
                    {
                        var      realType  = types[0];
                        string[] enumNames = Enum.GetNames(realType);
                        var      et        = new MetaEnumType {
                            ShortName = realType.Name,
                            Namespace = realType.Namespace,
                            Values    = enumNames
                        };
                        if (!_enumList.Exists(x => x.ShortName == realType.Name))
                        {
                            _enumList.Add(et);
                        }
                    }
                }
            }


            // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately
            if (meta.HasIdentifierProperty && !inheritedProperties.Contains(meta.IdentifierPropertyName))
            {
                var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType, false, true, false);
                dmap.IsIdentityColumn = (meta.IdentifierType.ReturnedClass == typeof(NHibernate.Id.IdentityGenerator));
                dataList.Insert(0, dmap);
            }
            else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType)
            {
                // composite key is a ComponentType
                var compType = (ComponentType)meta.IdentifierType;

                // check that the component belongs to this class, not a superclass
                if (compType.ReturnedClass == type || meta.IdentifierPropertyName == null || !inheritedProperties.Contains(meta.IdentifierPropertyName))
                {
                    var compNames = compType.PropertyNames;
                    for (int i = 0; i < compNames.Length; i++)
                    {
                        var compName = compNames[i];

                        var propType = compType.Subtypes[i];
                        if (!propType.IsAssociationType)
                        {
                            var dmap = MakeDataProperty(compName, propType, compType.PropertyNullability[i], true, false);
                            dataList.Insert(0, dmap);
                        }
                        else
                        {
                            var assProp = MakeAssociationProperty(persister, (IAssociationType)propType, compName, dataList, true);
                            navList.Add(assProp);
                        }
                    }
                }
            }

            // We do the association properties after the data properties, so we can do the foreign key lookups
            for (int i = 0; i < propNames.Length; i++)
            {
                var propName = propNames[i];
                if (inheritedProperties.Contains(propName))
                {
                    continue;                                  // skip property defined on superclass
                }
                var propType = propTypes[i];
                if (propType.IsAssociationType)
                {
                    // navigation property
                    var assProp = MakeAssociationProperty(persister, (IAssociationType)propType, propName, dataList, false);
                    navList.Add(assProp);
                }
            }
        }