示例#1
0
        private void ValidateTable(Type entityType, IEnumerable <SchemaTableColumn> schemaTableColumns, string tableName)
        {
            var error = new Dictionary <string, bool>();

            var propertiesMapping = entityType
                                    .GetRuntimeProperties()
                                    .Where(x => x.IsPrimitive())
                                    .OrderBy(_conventions.GetColumnOrderOrDefault)
                                    .ToDictionary(_conventions.GetColumnName, x => x);

            var columns = propertiesMapping.Keys.ToArray();

            // Ensure we have the same number of columns and they all have the same name
            if (schemaTableColumns.Count() != columns.Length)
            {
                error["ColumnCount_Mismatch"] = true;
            }

            if (!schemaTableColumns.All(x => columns.Contains(x.ColumnName)))
            {
                error["ColumnName_Mismatch"] = true;
            }

            if (error.Any())
            {
                throw new InvalidOperationException(string.Format(Resources.SchemaTableColumnsMismatch, entityType.Name));
            }

            // Gets all the constraints
            var schemaTableColumnConstraintsMapping = GetSchemaTableColumnConstraintsMapping(tableName, columns);
            var primaryKeyPropertiesMapping         = _conventions.GetPrimaryKeyPropertyInfos(entityType).ToDictionary(_conventions.GetColumnName, x => x);

            // Gets all the foreign keys
            var foreignKeyPropertyInfosMapping = entityType
                                                 .GetRuntimeProperties()
                                                 .Where(x => x.IsComplex())
                                                 .Select(pi => _conventions.GetForeignKeyPropertyInfos(entityType, pi.PropertyType)
                                                         .ToDictionary(_conventions.GetColumnName, x => pi))
                                                 .SelectMany(x => x)
                                                 .ToDictionary(x => x.Key, x => x.Value);

            // Validate all the columns
            foreach (var schemaTableColumn in schemaTableColumns)
            {
                var columnName   = schemaTableColumn.ColumnName;
                var propertyInfo = propertiesMapping[columnName];

                // Property type
                var columnDataType = DbHelper.MapToType(schemaTableColumn.DataType);
                if (columnDataType != propertyInfo.PropertyType)
                {
                    error["PropertyType_Mismatch"] = true;
                }

                // Property order
                if (!error.Any())
                {
                    var columnAttribute = propertyInfo.GetCustomAttribute <ColumnAttribute>();
                    if (columnAttribute != null && columnAttribute.Order != -1)
                    {
                        var order = schemaTableColumn.OrdinalPosition;

                        // This is cant be a simple 'schemaTableColumn.OrdinalPosition != columnAttribute.Order' to check for a mismatch...
                        // if the type has foreign composite keys, the foreign keys will have an ordering attribute that matches the one on the
                        // foreign entity primary keys, not necessarily the ones that are in the sql database
                        if (foreignKeyPropertyInfosMapping.ContainsKey(columnName))
                        {
                            var foreignPropertyInfo = foreignKeyPropertyInfosMapping[columnName];

                            if (_conventions.HasCompositePrimaryKey(foreignPropertyInfo.PropertyType))
                            {
                                order = schemaTableColumn.OrdinalPosition - (schemaTableColumn.OrdinalPosition - columnAttribute.Order);
                            }
                        }

                        if (order != columnAttribute.Order)
                        {
                            error["OrdinalPosition_Mismatch"] = true;
                        }
                    }
                }

                // Property constraints
                if (!error.Any())
                {
                    var requiredAttribute = propertyInfo.GetCustomAttribute <RequiredAttribute>();
                    var canBeNull         = !propertyInfo.PropertyType.IsValueType || Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
                    if (canBeNull && schemaTableColumn.IsNullable == "NO")
                    {
                        if (requiredAttribute == null && !primaryKeyPropertiesMapping.ContainsKey(columnName))
                        {
                            error["IsNullable_Mismatch"] = true;
                        }
                    }

                    if (schemaTableColumnConstraintsMapping != null &&
                        schemaTableColumnConstraintsMapping.ContainsKey(columnName))
                    {
                        var constraint = schemaTableColumnConstraintsMapping[columnName];

                        switch (constraint)
                        {
                        case SchemaTableConstraintType.NotNull:
                        {
                            if (requiredAttribute == null)
                            {
                                error["IsNullable_Mismatch"] = true;
                            }

                            break;
                        }

                        case SchemaTableConstraintType.PrimaryKey:
                        {
                            if (!primaryKeyPropertiesMapping.ContainsKey(columnName))
                            {
                                error["PrimaryKey_Mismatch"] = true;
                            }

                            break;
                        }
                        }
                    }
                }

                // Property length
                if (!error.Any())
                {
                    var stringLengthAttribute = propertyInfo.GetCustomAttribute <StringLengthAttribute>();
                    if (stringLengthAttribute != null)
                    {
                        if (schemaTableColumn.CharacterMaximunLength != stringLengthAttribute.MaximumLength)
                        {
                            error["CharacterMaximunLength_Mismatch"] = true;
                        }
                    }
                }

                if (error.Any())
                {
                    throw new InvalidOperationException(string.Format(Resources.SchemaTableColumnsMismatch, entityType.Name));
                }
            }
        }