Postgresql的Asp.net Mvc MigrationSqlGenerator给了我一个错误

时间:2012-11-12 14:31:51

标签: entity-framework c#-4.0 asp.net-mvc-4 migration

我已禁用自动迁移,我为Postgresql创建了一个新的MigrationSqlGenerator:

    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        SetSqlGenerator("Npgsql", new PostgreSqlMigrationSqlGenerator());
    }

在Package Manager控制台中,我执行命令“Update-Database -Verbose”。所有迁移都正确执行,它完美地创建了Schema和所有表(包括__MigrationHistory表)。在创建结束时,它向我显示了这个错误:

    System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ToInt32(String value)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.BuildColumnModel(XElement property, String entitySetName, ModelMetadata modelMetadata)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.BuildAlterColumnOperation(String table, XElement targetProperty, String targetEntitySetName, ModelMetadata targetModelMetadata, XElement sourceProperty, String sourceEntitySetName, ModelMetadata sourceModelMetadata)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.<FindChangedColumns>b__ef(<>f__AnonymousType1d`2 <>h__TransparentIdentifiere5)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, String connectionString)
   at System.Data.Entity.Migrations.DbMigrator.IsModelOutOfDate(XDocument model, DbMigration lastMigration)
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
Input string was not in a correct format.

__MigrationHistory为空。没有人登记登记。 我克隆了EF项目,它似乎在以下方法中得到错误:

public IEnumerable<MigrationOperation> Diff(XDocument sourceModel, XDocument targetModel, bool? includeSystemOperations = null)
    {
        DbProviderInfo providerInfo;

        _source
            = new ModelMetadata
                  {
                      Model = sourceModel,
                      StoreItemCollection = sourceModel.GetStoreItemCollection(out providerInfo),
                      ProviderManifest = GetProviderManifest(providerInfo),
                      ProviderInfo = providerInfo
                  };

        _target
            = new ModelMetadata
                  {
                      Model = targetModel,
                      StoreItemCollection = targetModel.GetStoreItemCollection(out providerInfo),
                      ProviderManifest = GetProviderManifest(providerInfo),
                      ProviderInfo = providerInfo
                  };

        _consistentProviders
            = _source.ProviderInfo.ProviderInvariantName.EqualsIgnoreCase(
                _target.ProviderInfo.ProviderInvariantName)
              && _source.ProviderInfo.ProviderManifestToken.EqualsIgnoreCase(
                  _target.ProviderInfo.ProviderManifestToken);

        var renamedColumns = FindRenamedColumns().ToList();
        var addedColumns = FindAddedColumns(renamedColumns).ToList();
        var alteredColumns = FindChangedColumns().ToList();
        var removedColumns = FindRemovedColumns(renamedColumns).ToList();
        var renamedTables = FindRenamedTables().ToList();
        var movedTables = FindMovedTables().ToList();
        var addedTables = FindAddedTables(renamedTables).ToList();

        var columnNormalizedSourceModel = BuildColumnNormalizedSourceModel(renamedColumns);

        var addedForeignKeys = FindAddedForeignKeys(columnNormalizedSourceModel).ToList();
        var removedTables = FindRemovedTables(renamedTables).ToList();
        var removedForeignKeys = FindRemovedForeignKeys(columnNormalizedSourceModel).ToList();
        var changedPrimaryKeys = FindChangedPrimaryKeys(columnNormalizedSourceModel).ToList();

        if (includeSystemOperations == null)
        {
            includeSystemOperations
                = sourceModel.HasSystemOperations() && targetModel.HasSystemOperations();
        }

        return renamedTables
            .Concat<MigrationOperation>(movedTables)
            .Concat(removedForeignKeys)
            .Concat(removedForeignKeys.Select(fko => fko.CreateDropIndexOperation()))
            .Concat(renamedColumns)
            .Concat(addedTables)
            .Concat(addedColumns)
            .Concat(alteredColumns)
            .Concat(changedPrimaryKeys)
            .Concat(addedForeignKeys.Select(fko => fko.CreateCreateIndexOperation()))
            .Concat(addedForeignKeys)
            .Concat(removedColumns)
            .Concat(removedTables)
            .Where(o => (includeSystemOperations == true) || !o.IsSystem)
            .ToList();
    }

我不知道为什么,而且我不能在这个错误的前面继续前进。有人知道如何解决这个问题吗?

更新

我已经实现了Generate(InsertHistoryOperation insertHistoryOperation)方法来添加迁移历史记录,如下所示:

protected override void Generate(InsertHistoryOperation insertHistoryOperation)
    {

        using (var writer = Writer())
        {

            writer.Write("INSERT INTO \"dbo\".\"__MigrationHistory\" (\"MigrationId\", \"Model\", \"ProductVersion\") VALUES ('");

            writer.Write(insertHistoryOperation.MigrationId + "old");

            writer.Write("',E'");

            writer.Write("x0" + insertHistoryOperation.Model.ToHexString());

            writer.Write("','");

            writer.Write(insertHistoryOperation.ProductVersion);

            writer.Write("')");

            Statement(writer);

        }

    }

数据库似乎创造得很完美,但错误仍然让我拉扯我的头发。我是以错误的方式保存模型吗?

在EF的EdmModelDiffer.cs尝试将MaxLength转换为int时,应该在此例程中引发错误。

private static ColumnModel BuildColumnModel(
        XElement property, string entitySetName, ModelMetadata modelMetadata)
    {
        Contract.Requires(property != null);
        Contract.Requires(!string.IsNullOrWhiteSpace(entitySetName));
        Contract.Requires(modelMetadata != null);

        var nameAttribute = property.NameAttribute();
        var nullableAttribute = property.NullableAttribute();
        var maxLengthAttribute = property.MaxLengthAttribute();
        var precisionAttribute = property.PrecisionAttribute();
        var scaleAttribute = property.ScaleAttribute();
        var storeGeneratedPatternAttribute = property.StoreGeneratedPatternAttribute();
        var storeType = property.TypeAttribute();

        var entityType
            = modelMetadata.StoreItemCollection
                .OfType<EntityType>()
                .Single(et => et.Name.EqualsIgnoreCase(entitySetName));

        var edmProperty
            = entityType.Properties[nameAttribute];

        var typeUsage = modelMetadata.ProviderManifest.GetEdmType(edmProperty.TypeUsage);

        var defaultStoreTypeName = modelMetadata.ProviderManifest.GetStoreType(typeUsage).EdmType.Name;

        var column
            = new ColumnModel(((PrimitiveType)edmProperty.TypeUsage.EdmType).PrimitiveTypeKind, typeUsage)
                  {
                      Name = nameAttribute,
                      IsNullable
                          = !string.IsNullOrWhiteSpace(nullableAttribute)
                            && !Convert.ToBoolean(nullableAttribute, CultureInfo.InvariantCulture)
                                ? false
                                : (bool?)null,
                      MaxLength
                          = !string.IsNullOrWhiteSpace(maxLengthAttribute)
                                ? Convert.ToInt32(maxLengthAttribute, CultureInfo.InvariantCulture)
                                : (int?)null,
                      Precision
                          = !string.IsNullOrWhiteSpace(precisionAttribute)
                                ? Convert.ToByte(precisionAttribute, CultureInfo.InvariantCulture)
                                : (byte?)null,
                      Scale
                          = !string.IsNullOrWhiteSpace(scaleAttribute)
                                ? Convert.ToByte(scaleAttribute, CultureInfo.InvariantCulture)
                                : (byte?)null,
                      StoreType
                          = !storeType.EqualsIgnoreCase(defaultStoreTypeName)
                                ? storeType
                                : null
                  };

        column.IsIdentity
            = !string.IsNullOrWhiteSpace(storeGeneratedPatternAttribute)
              && storeGeneratedPatternAttribute.EqualsIgnoreCase("Identity")
              && _validIdentityTypes.Contains(column.Type);

        Facet facet;
        if (typeUsage.Facets.TryGetValue(DbProviderManifest.FixedLengthFacetName, true, out facet)
            && facet.Value != null
            && (bool)facet.Value)
        {
            column.IsFixedLength = true;
        }

        if (typeUsage.Facets.TryGetValue(DbProviderManifest.UnicodeFacetName, true, out facet)
            && facet.Value != null
            && !(bool)facet.Value)
        {
            column.IsUnicode = false;
        }

        var isComputed
            = !string.IsNullOrWhiteSpace(storeGeneratedPatternAttribute)
              && storeGeneratedPatternAttribute.EqualsIgnoreCase("Computed");

        if ((column.Type == PrimitiveTypeKind.Binary)
            && (typeUsage.Facets.TryGetValue(DbProviderManifest.MaxLengthFacetName, true, out facet)
                && (facet.Value is int)
                && ((int)facet.Value == 8))
            && isComputed)
        {
            column.IsTimestamp = true;
        }

        return column;
    }

0 个答案:

没有答案