2

我正在使用 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”表中),上下文应该信任我的数据库

4

2 回答 2

1

最后!

出于某种感觉,我检查了应用程序的 AppPool 设置并将“启用 32 位应用程序”从“false”更改为“true”,并且 Web 应用程序能够访问数据库。

我不知道为什么,但我会试着找出答案。

更新

显然我不是第一个使用 EntityFramework + Windows Server 2008 R2 64bits + IIS 7.5 和“启用 32 位”选项发现错误的人:

这里 这里

然而,在他们的情况下,症状是不同的。

于 2013-08-27T19:48:02.543 回答
0

听起来您在某处缺少主键。

确保您的实体有一个密钥,确保它是“属性”(具有 get/set),并且它是“PUBLIC”。

最后,尝试右键单击模型,然后选择“从数据库更新模型”

链接:

于 2013-08-27T17:04:00.170 回答