/// <summary>
        /// Get name of the column used by EF.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context">DbContext</param>
        /// <param name="rootEntityType">Entity type to find property of. In case of owned entity specify parent entity type.</param>
        /// <param name="expression">Property of entity that is used to get column name.</param>
        /// <returns></returns>
        internal static string GetColumnName(this DbContext context, Type rootEntityType, MemberExpression expression)
        {
            List <string> propertyNamePath = ReflectionUtility.GetMemberPath(expression);
            string        propertyName     = ReflectionUtility.ConcatenateEfPropertyName(propertyNamePath);

            return(GetColumnName(context, rootEntityType, propertyName));
        }
        /// <summary>
        /// Get name of the column used by EF.
        /// </summary>
        /// <typeparam name="T">Entity type</typeparam>
        /// <param name="context">DbContext</param>
        /// <param name="property">Property of entity that is used to get column name</param>
        /// <returns></returns>
        public static string GetColumnName <T>(this DbContext context, Expression <Func <T, object> > expression)
        {
            List <string> propertyNamePath = ReflectionUtility.GetMemberNamePath(expression);

            Type   rootEntityType = typeof(T);
            string propertyName   = ReflectionUtility.ConcatenateEfPropertyName(propertyNamePath);

            return(GetColumnName(context, rootEntityType, propertyName));
        }
예제 #3
0
        protected List <MappedProperty> GetPropertiesHierarchy(Type propertyType, List <string> parentPropertyNames)
        {
            if (parentPropertyNames.Count == 2)
            {
                throw new NotImplementedException("More than 1 level of Entity framework owned entities is not supported.");
            }

            List <MappedProperty> list = new List <MappedProperty>();

            //Include all primitive properties
            BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            PropertyInfo[]      allEntityProperties = propertyType.GetProperties(bindingFlags);
            List <PropertyInfo> primitiveProperties = allEntityProperties.Where(
                p =>
            {
                Type underlying = Nullable.GetUnderlyingType(p.PropertyType);
                Type property   = underlying ?? p.PropertyType;
                return(property.IsValueType == true ||
                       property.IsPrimitive ||
                       property == typeof(string));
            })
                                                      .ToList();

            //Exclude ignored properties
            IEntityType efEntityType = null;

            if (propertyType == _rootEntityType)
            {
                efEntityType = _efRootEntityType;
            }
            else
            {
                string propertyName = parentPropertyNames[0];
                efEntityType = _context.GetOwnedProperty(_efRootEntityType, propertyName);
            }

            List <string> efMappedProperties = efEntityType.GetProperties()
                                               .Select(x => x.Name)
                                               .ToList();

            primitiveProperties = primitiveProperties
                                  .Where(x => efMappedProperties.Contains(x.Name))
                                  .ToList();

            //Return all the rest properties
            foreach (PropertyInfo supportedProp in primitiveProperties)
            {
                List <string> namesHierarchy = parentPropertyNames.ToList();
                namesHierarchy.Add(supportedProp.Name);

                string    efDefaultName = ReflectionUtility.ConcatenateEfPropertyName(namesHierarchy);
                IProperty property      = DbContextExtensions.GetPropertyMapping(_context, _rootEntityType, efDefaultName);
                list.Add(new MappedProperty
                {
                    PropertyInfo      = supportedProp,
                    EfDefaultName     = efDefaultName,
                    EfMappedName      = property.GetColumnName(),
                    ConfiguredSqlType = property.GetColumnType()
                });
            }

            //Add complex properties
            List <MappedProperty> complexProperties = GetComplexProperties(allEntityProperties, parentPropertyNames);

            list.AddRange(complexProperties);
            return(list);
        }
        protected List <MappedProperty> GetPropertiesHierarchy(Type rootType, Type propertyType, List <string> parentPropertyNames)
        {
            List <MappedProperty> list = new List <MappedProperty>();

            BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            PropertyInfo[]      allEntityProperties = propertyType.GetProperties(bindingFlags);
            List <PropertyInfo> mappedProperties    = allEntityProperties.Where(
                p =>
            {
                Type underlined = Nullable.GetUnderlyingType(p.PropertyType);
                Type property   = underlined ?? p.PropertyType;
                return(property.IsValueType == true ||
                       property.IsPrimitive ||
                       property == typeof(string));
            })
                                                      .ToList();

            foreach (PropertyInfo supportedProp in mappedProperties)
            {
                List <string> namesHierarchy = parentPropertyNames.ToList();
                namesHierarchy.Add(supportedProp.Name);

                string efDefaultName = ReflectionUtility.ConcatenateEfPropertyName(namesHierarchy);
                string efMappedName  = DbContextExtensions.GetColumnName(_context, rootType, efDefaultName);
                list.Add(new MappedProperty
                {
                    PropertyInfo  = supportedProp,
                    EfDefaultName = efDefaultName,
                    EfMappedName  = efMappedName
                });
            }

            List <PropertyInfo> complexProperties = allEntityProperties.Where(
                p => p.PropertyType != typeof(string) &&
                p.PropertyType.IsClass)
                                                    .ToList();

            //Exclude navigation properties
            //ICollection properties are excluded already as interfaces and not classes.
            //Here we exclude virtual properties that are not ICollection, by checking if they are virtual.
            complexProperties = complexProperties
                                .Where(x => x.GetAccessors()[0].IsVirtual == false)
                                .ToList();

            foreach (PropertyInfo complexProp in complexProperties)
            {
                List <string> namesHierarchy = parentPropertyNames.ToList();
                namesHierarchy.Add(complexProp.Name);

                List <MappedProperty> childProperties = GetPropertiesHierarchy(rootType, complexProp.PropertyType, namesHierarchy);
                if (childProperties.Count > 0)
                {
                    list.Add(new MappedProperty
                    {
                        PropertyInfo    = complexProp,
                        ChildProperties = childProperties
                    });
                }
            }

            return(list);
        }