我已禁用自动迁移,并为 Postgresql 创建了一个新的 MigrationSqlGenerator:
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("Npgsql", new PostgreSqlMigrationSqlGenerator());
}
从包管理器控制台,我执行命令“Update-Database -Verbose”。所有迁移都正确执行,它完美地创建了模式和所有表(包括 __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;
}