【问题标题】:Error using Entity Framework 5 with SQL Server 2012将实体框架 5 与 SQL Server 2012 一起使用时出错
【发布时间】:2013-08-27 16:58:26
【问题描述】:

我正在使用 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,另一个只有读/写权限),但没有填充它。我想使用 EF 迁移,使用 dbo 用户。

在我的开发工作站中,针对 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' 没有定义键。定义此 EntityType 的键。 [对每个实体重复] \tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'UserFiles' 基于没有定义键的类型'UserProfile'。 [对每个实体重复

  • 我有generated a Script using Migration,将它发送到服务器,然后我在数据库上手动执行它。我将应用程序发布到服务器,“发布”配置,针对 SQL 2012 并使用迁移(作为数据库初始化程序)。同样的错误。

  • 我创建了一个小型 ConsoleApplication,它引用了我的数据访问库。它唯一做的就是以与 Web 应用程序相同的方式初始化上下文(将 Database.SetInitializer 设置为使用迁移并创建上下文)。我已经将它发送到服务器并执行了它。 它运行没有问题!表在数据库中正确创建,没有抛出异常

我的 Web 应用程序似乎以某种方式损坏了。我必须找到哪里。

令人沮丧。为什么它不能识别我的模型?我还使用 NLog 来检查 OnModelCreating 是否已被击中。我相信如果没有找到元数据信息(我认为存储在“__MigrationHistory”表中),the context should trust my database

【问题讨论】:

  • 你能告诉我们你的一个班级抛出这个错误吗?我想检查您是否在您的实体中使用IdEntityId[Key]
  • 你能展示LoadConfiguration方法吗?显然由于某种原因它不起作用。
  • 这可能是完全信任(开发环境)与中(或更低)信任(实时环境)的事情吗?那时LoadConfigurations 中的反射可能无法正常工作。我不确定,只是一个非常模糊的假设......
  • @Slauma,请看一下我在编辑中的最后一个测试。
  • 嗯,信任级别设置(通常在 .NET 安装目录中的 machine.config 中)是 ASP.NET 设置,因此控制台应用程序可以运行而 Web 应用程序不能运行。这是“您的”服务器还是托管服务提供商的服务器?我会在LoadConfigurations 中添加一些调试代码,例如将foreach 循环正在迭代的配置类型名称写入文本文件。该异常看起来确实像将配置添加到模型构建器由于某种原因而失败。

标签: c# asp.net sql-server entity-framework


【解决方案1】:

终于!

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

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

更新

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

Here Here

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

【讨论】:

    【解决方案2】:

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

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

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

    链接:

    【讨论】:

    • Paul,我使用 CodeFirst,POCO 和配置都是由我创建的。此外,它在我的开发工作站上运行良好,带有 LocalDb(或 SQL CE)。我使用 EF Code First 创建了其他应用程序。我有一个本地应用程序 (WPF) 在 Code First 和 Migrations 中运行良好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多