我正在使用 Visual Studio 2012 Web 发布功能将 ASP.MVC 4.0 应用程序部署到带有 IIS 7.5 的 Windows Server 2008 R2。该应用程序面向 .NET 4.5,它使用 EntityFramework 5.0 Code First 进行数据访问。目标数据库是 SQL Server 2012 的一个实例。
在服务器中,我在 SQL Server 2012 上手动创建了数据库和用户(一个 dbo,另一个只有读/写权限),但没有填充它。我想使用 dbo 用户来使用 EF 迁移。
在我的开发工作站中,针对 LocalDb 的数据库一切正常,所以我假设我的上下文和映射是正确的。
但是,当我将应用程序部署到服务器并尝试运行它时,我不断收到以下异常:
System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation:
System.Data.Entity.Edm.EdmEntityType : EntityType "Entity" has no key defined. Define the key for this EntityType.
对于我的上下文的每个实体,“EntityType 没有定义键”重复。
我已经检查了 web.config,并且正在按预期部署连接字符串。
数据库的初始化发生在 Application_Start 中:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Poip.Web.Domain.Migrations.Configuration>());
using (var context = new MyContext())
context.Database.Initialize(true);
我的背景很简单,就像我的实体一样。然后我使用 EntityTypeConfiguration 类进行配置,然后在上下文的 OnModelCreating 方法中加载。正如我所提到的,它适用于 LocalDb(或 SqlCompact)。实体示例:
public class UserFile
{
public int UserFileKey { get; set; }
// TODO: Utilizar este campo para verificar integridade do arquivo
public string Hash { get; set; }
public string FilePath { get; set; }
public string OriginalFileName { get; set; }
public Guid Guid { get; set; }
public long Size { get; set; }
public int UserKey { get; set; }
public UserProfile User { get; set; }
public UserFile()
{
this.Guid = Guid.NewGuid();
}
}
internal class UserFileMap : EntityTypeConfiguration<UserFile>
{
public UserFileMap()
{
this.HasKey(e => e.UserFileKey);
this.Property(e => e.UserFileKey)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(e => e.FilePath)
.IsRequired()
.HasMaxLength(255);
this.HasRequired(e => e.User)
.WithMany()
.HasForeignKey(e => e.UserKey);
}
}
我的上下文简化了:
public class MyContext : DbContext
{
public MyContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<UserFile> UserFiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>();
modelBuilder.LoadConfigurations();
}
}
LoadConfigurations
是一种加载程序集的所有 EntityTypeConfiguration 类的方法。它已经在其他应用程序中进行了测试,并且再次在我的开发工作站上运行。
我已经尝试完全放弃迁移。我使用迁移来生成脚本。我从脚本中删除了“__MigrationHistory”表,并在服务器上执行它来创建表。然后我将初始化更改为:
Database.SetInitializer<MyContext>(null);
using (var context = new MyContext())
context.Database.Initialize(true);
但我继续得到同样的例外。
我不知道接下来要检查什么。任何帮助,将不胜感激。
编辑
LoadConfigurations
方法:
public static void LoadConfigurations(this DbModelBuilder builder)
{
LoadConfigurations(builder, Assembly.GetCallingAssembly());
}
public static void LoadConfigurations(this DbModelBuilder builder, Assembly assembly)
{
var configurationTypes = assembly.GetTypes()
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (dynamic configuration in configurationTypes.Select(type => Activator.CreateInstance(type)))
{
builder.Configurations.Add(configuration);
}
}
更新
我做了一些测试:
我已经在本地运行应用程序,“调试”配置,以 LocalDb 为目标并使用迁移。该应用程序没有问题。.mdf 文件已创建,表也已创建。
我已经将应用程序发布到服务器,“调试”配置,定位 LocalDb 并使用迁移。我有以下黄色死屏:
[Win32Exception (0x80004005): 系统找不到指定的文件]
[SqlException (0x80131904): 建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误
我相信仅安装 Sql Server 2012 不支持 LocalDb。
我已经使用迁移将应用程序发布到服务器,“发布”配置,针对 SQL Server 2012 数据库。db 已经创建,为空,指定的用户是 dbo。错误:
在模型生成期间检测到一个或多个验证错误:\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'UserFile' has no key defined。定义此 EntityType 的键。[对每个实体重复] \tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'UserFiles' 基于没有定义键的类型 'UserProfile'。[对每个实体重复
我已经使用 Migration 生成了一个脚本,将它发送到服务器,然后我在数据库上手动执行它。我将应用程序发布到服务器,“发布”配置,针对 SQL 2012 并使用迁移(作为数据库初始化程序)。同样的错误。
我创建了一个小型 ConsoleApplication,它引用了我的数据访问库。它唯一要做的就是以与 Web 应用程序相同的方式初始化上下文(设置 Database.SetInitializer 以使用迁移并创建上下文)。我已经将它发送到服务器并执行了它。它运行没有问题!这些表在数据库中正确创建,并且没有引发异常。
我的网络应用程序似乎以某种方式损坏了。我必须找到在哪里。
它令人沮丧。为什么它不能识别我的模型?我还使用 NLog 来检查 OnModelCreating 是否已被击中。我相信如果没有找到元数据信息(我认为存储在“__MigrationHistory”表中),上下文应该信任我的数据库。