为什么 EF 说我的模型已经改变而实际上没有?
Why is EF saying my model has changed when it has not?
我不断收到以下错误:
System.InvalidOperationException: The model backing the 'McContext'
context has changed since the database was created. Consider using
Code First Migrations to update the database
(http://go.microsoft.com/fwlink/?LinkId=238269).
我正在使用来自 nuget v6.1.3 的最新 Entity Framework 创建一个 .NET MVC 5 网站。我附加到本地 MDF 文件,因为我没有在本地安装 SQL Server 或 Express。我正在使用 Code First 模型。
我昨天和今天花了几个小时梳理关于这个错误的 SO 和 WWW 帖子,但没有找到有效的解决方案。他们中的大多数围绕不同类型的初始化器,或者关于代码如何首先需要迁移或模型更改的初始化器的简短解释。但是我是运行通过PM控制台手动设置的。我在下面包含了我的步骤。
连接字符串:
<add name="testSQLConnection" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\jwatts\Documents\Visual Studio 2015\Projects\MyProject\Databases\MyProject01.mdf;Integrated Security=True;Connect Timeout=30" providerName="System.Data.SqlClient" />
型号:
public class Family
{
public Family() { }
[Key, Index(IsUnique = true)]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(128)]
public string Name { get; set; }
[StringLength(1024)]
public string Description { get; set; }
public DateTime Created { get; set; }
public string CreatedBy { get; set; }
public DateTime? Changed { get; set; }
public string ChangedBy { get; set; }
public DateTime? Deleted { get; set; }
public string DeletedBy { get; set; }
}
上下文:
public class McContext : DbContext
{
public McContext() : base("testSQLConnection") { }
public DbSet<Family> Families { get; set; }
}
配置:
internal sealed class Configuration : DbMigrationsConfiguration<Data.McContext>
{
public Configuration()
{
MigrationsDirectory = @"Data\Migrations";
AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(McContext context)
{
context.Families.Add(new Family()
{
Name = "My Family",
Description = "The family",
Created = DateTime.Now,
CreatedBy = "system"
});
context.SaveChanges();
}
}
自动生成迁移 class:
public partial class StartupConfig : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Families",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 128),
Description = c.String(maxLength: 1024),
Created = c.DateTime(nullable: false),
CreatedBy = c.String(),
Changed = c.DateTime(),
ChangedBy = c.String(),
Deleted = c.DateTime(),
DeletedBy = c.String(),
})
.PrimaryKey(t => t.Id)
.Index(t => t.Id, unique: true);
}
public override void Down()
{
DropIndex("dbo.Families", new[] { "Id" });
DropTable("dbo.Families");
}
}
单元测试代码:
[TestMethod]
public void CreateTheContext_Test()
{
using (var ctx = new McContext())
{
//error on this line below:
var fam = ctx.Families.Where(f => f.Name.Contains("My")).FirstOrDefault();
Assert.IsTrue(fam != null && fam.Name.Contains("My"));
}
}
休闲步骤:
- 我从 "clean slate" 开始,删除了我测试数据库中的所有数据库 table,并删除了所有 Data\Migrations.
- 重建解决方案。 (基础项目和单元测试项目)
- 在程序包管理器控制台中,运行“
Add-Migration StartupConfig
”
- 迁移文件已添加到 Data\Migrations,名为“
{datetime}_StartupConfig.cs
”。参见上文 StartupConfig
class。
- 我构建了项目。
- 我运行“
Update-Database -TargetMigration:StartupConfig
”
- PM控制台输出4行,包括"Running Seed method",成功完成。
- 我通过 SQL 查询确认“
__MigrationHistory
”和“Families
”table 已添加到数据库中,并且每个 table有 1 条记录。
- 我运行单元测试并收到错误。
我有一个更复杂的模型,但我开始一个一个地删除东西,使事情尽可能简单。但是我不能比这更简单了,但错误仍然存在。值得注意的是,对于这个特定项目,我从未从单元测试中获得成功的查询。
当我在上面输入这些重新创建的步骤时,我同时执行了这些步骤,并且遇到了同样的错误。
我不知道接下来要尝试什么?
因为你是代码,所以它没有改变,它必须与迁移 table(具有你的数据库模型信息的那个)或你正在使用的数据库文件有关。
我会建议安装 Sql server express 并重试一切。由于您正在创建的数据库是一个文件,因此您将面临更多风险。
编辑:
尝试查看您的项目正在使用的实例的名称。默认情况下 EF 使用 DefaultConnection。检查所有项目中的 web.config 或配置文件。
在根据@AaronLS 的建议检查单元测试中的连接字符串时,我发现连接字符串不同。
事实证明,单元测试的 App.config 没有连接字符串并且将 "sqlTestConnection" 视为数据库名称,因为它无法解析它。
将连接字符串添加到 App.config 解决了问题。
我不断收到以下错误:
System.InvalidOperationException: The model backing the 'McContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
我正在使用来自 nuget v6.1.3 的最新 Entity Framework 创建一个 .NET MVC 5 网站。我附加到本地 MDF 文件,因为我没有在本地安装 SQL Server 或 Express。我正在使用 Code First 模型。
我昨天和今天花了几个小时梳理关于这个错误的 SO 和 WWW 帖子,但没有找到有效的解决方案。他们中的大多数围绕不同类型的初始化器,或者关于代码如何首先需要迁移或模型更改的初始化器的简短解释。但是我是运行通过PM控制台手动设置的。我在下面包含了我的步骤。
连接字符串:
<add name="testSQLConnection" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\jwatts\Documents\Visual Studio 2015\Projects\MyProject\Databases\MyProject01.mdf;Integrated Security=True;Connect Timeout=30" providerName="System.Data.SqlClient" />
型号:
public class Family
{
public Family() { }
[Key, Index(IsUnique = true)]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[StringLength(128)]
public string Name { get; set; }
[StringLength(1024)]
public string Description { get; set; }
public DateTime Created { get; set; }
public string CreatedBy { get; set; }
public DateTime? Changed { get; set; }
public string ChangedBy { get; set; }
public DateTime? Deleted { get; set; }
public string DeletedBy { get; set; }
}
上下文:
public class McContext : DbContext
{
public McContext() : base("testSQLConnection") { }
public DbSet<Family> Families { get; set; }
}
配置:
internal sealed class Configuration : DbMigrationsConfiguration<Data.McContext>
{
public Configuration()
{
MigrationsDirectory = @"Data\Migrations";
AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(McContext context)
{
context.Families.Add(new Family()
{
Name = "My Family",
Description = "The family",
Created = DateTime.Now,
CreatedBy = "system"
});
context.SaveChanges();
}
}
自动生成迁移 class:
public partial class StartupConfig : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Families",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 128),
Description = c.String(maxLength: 1024),
Created = c.DateTime(nullable: false),
CreatedBy = c.String(),
Changed = c.DateTime(),
ChangedBy = c.String(),
Deleted = c.DateTime(),
DeletedBy = c.String(),
})
.PrimaryKey(t => t.Id)
.Index(t => t.Id, unique: true);
}
public override void Down()
{
DropIndex("dbo.Families", new[] { "Id" });
DropTable("dbo.Families");
}
}
单元测试代码:
[TestMethod]
public void CreateTheContext_Test()
{
using (var ctx = new McContext())
{
//error on this line below:
var fam = ctx.Families.Where(f => f.Name.Contains("My")).FirstOrDefault();
Assert.IsTrue(fam != null && fam.Name.Contains("My"));
}
}
休闲步骤:
- 我从 "clean slate" 开始,删除了我测试数据库中的所有数据库 table,并删除了所有 Data\Migrations.
- 重建解决方案。 (基础项目和单元测试项目)
- 在程序包管理器控制台中,运行“
Add-Migration StartupConfig
” - 迁移文件已添加到 Data\Migrations,名为“
{datetime}_StartupConfig.cs
”。参见上文StartupConfig
class。 - 我构建了项目。
- 我运行“
Update-Database -TargetMigration:StartupConfig
” - PM控制台输出4行,包括"Running Seed method",成功完成。
- 我通过 SQL 查询确认“
__MigrationHistory
”和“Families
”table 已添加到数据库中,并且每个 table有 1 条记录。 - 我运行单元测试并收到错误。
我有一个更复杂的模型,但我开始一个一个地删除东西,使事情尽可能简单。但是我不能比这更简单了,但错误仍然存在。值得注意的是,对于这个特定项目,我从未从单元测试中获得成功的查询。
当我在上面输入这些重新创建的步骤时,我同时执行了这些步骤,并且遇到了同样的错误。
我不知道接下来要尝试什么?
因为你是代码,所以它没有改变,它必须与迁移 table(具有你的数据库模型信息的那个)或你正在使用的数据库文件有关。
我会建议安装 Sql server express 并重试一切。由于您正在创建的数据库是一个文件,因此您将面临更多风险。
编辑:
尝试查看您的项目正在使用的实例的名称。默认情况下 EF 使用 DefaultConnection。检查所有项目中的 web.config 或配置文件。
在根据@AaronLS 的建议检查单元测试中的连接字符串时,我发现连接字符串不同。
事实证明,单元测试的 App.config 没有连接字符串并且将 "sqlTestConnection" 视为数据库名称,因为它无法解析它。
将连接字符串添加到 App.config 解决了问题。