简体   繁体   English

在SQL Server 2012中使用Entity Framework 5时出错

[英]Error using Entity Framework 5 with SQL Server 2012

I'm deploying a ASP.MVC 4.0 application to a Windows Server 2008 R2, with IIS 7.5, using Visual Studio 2012 web publish features. 我正在使用Visual Studio 2012 Web发布功能将ASP.MVC 4.0应用程序部署到具有IIS 7.5的Windows Server 2008 R2。 The application targets .NET 4.5, and it uses EntityFramework 5.0 Code First for data access. 该应用程序面向.NET 4.5,并使用EntityFramework 5.0 Code First进行数据访问。 The target dabatase is an instance of SQL Server 2012. 目标dabatase是SQL Server 2012的实例。

In the server, I've manually created the database and users (one dbo and another with only read/write permissions) on SQL Server 2012, but not populated it . 在服务器中, 我已经在SQL Server 2012上手动创建了数据库和用户(一个dbo,另一个仅具有读/写权限),但没有填充它 I want to use EF Migrations, using the dbo user. 我想使用dbo用户使用EF迁移。

In my dev workstation, everything works fine with the database targeting LocalDb , so I assume my context and mappings are right. 在我的开发工作站中,所有与LocalDb为目标的数据库都可以正常工作 ,因此我假设上下文和映射是正确的。

However, when I deploy the application to the server and try to run it, I keep getting the following exception: 但是,当我将应用程序部署到服务器并尝试运行它时,我不断收到以下异常:

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.

The "EntityType has no key defined" repeats for each entity of my context. 对上下文的每个实体重复“ EntityType没有定义的键”。

I have checked the web.config and the connectionstrings are being deployed as expected. 我已经检查了web.config并按预期部署了连接字符串。

The initialization of the database occurs in the Application_Start: 数据库的初始化发生在Application_Start中:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Poip.Web.Domain.Migrations.Configuration>());
using (var context = new MyContext())
    context.Database.Initialize(true);

My context is simple, as my entities. 我的情况很简单,就像我的实体一样。 I configure then with EntityTypeConfiguration classes, loading then in the context's OnModelCreating method. 然后,我使用EntityTypeConfiguration类进行配置,然后将其加载到上下文的OnModelCreating方法中。 As I've mentioned, it works fine with LocalDb (or SqlCompact). 如前所述,它可以与LocalDb(或SqlCompact)一起使用。 An example of entity: 实体示例:

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);
    }
}

My context simplified: 我的上下文简化了:

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 is a method to load all EntityTypeConfiguration classes of the assembly. LoadConfigurations是一种加载程序集的所有EntityTypeConfiguration类的方法。 It's been tested in other applications and, again, it works on my dev workstation. 它已经在其他应用程序中经过测试,并且再次可以在我的开发工作站上运行。

I've tried dropping Migrations entirely. 我尝试完全放弃迁移。 I used migrations to generate a script. 我使用迁移来生成脚本。 I removed the "__MigrationHistory" table from the script, and I executed it on the server to create the tables. 我从脚本中删除了“ __MigrationHistory”表,并在服务器上执行了该表以创建表。 Then I changed the initialization to: 然后我将初始化更改为:

Database.SetInitializer<MyContext>(null);
using (var context = new MyContext())
    context.Database.Initialize(true);

But I continue to get the same exception. 但是我继续遇到同样的例外。

I don't have any clue for what to check next. 我不知道接下来要检查什么。 Any help would be appreciated. 任何帮助,将不胜感激。

EDIT 编辑

The LoadConfigurations method: 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);
    }
}

UPDATE UPDATE

I did some tests: 我做了一些测试:

  • I've run the application locally, "Debug" configuration, targeting LocalDb and using Migrations. 我已经在本地运行该应用程序,“调试”配置,定位到LocalDb并使用了Migrations。 The app worked with no problems. 该应用程序正常工作。 The .mdf file was created and the tables created as well. .mdf文件已创建,表也已创建。

  • I've published the app to the server, "Debug" configuration, targeting LocalDb and using Migrations. 我已经将该应用程序发布到服务器上,即“调试”配置,目标是LocalDb并使用“迁移”。 I've got the following yellow screen of death: 我有以下黄色的死亡画面:

    [Win32Exception (0x80004005): The system cannot find the file specified] [Win32Exception(0x80004005):系统找不到指定的文件]

    [SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server [SqlException(0x80131904):建立与SQL Server的连接时发生与网络相关或特定于实例的错误

    I believe LocalDb is not supported by only installing Sql Server 2012. 我相信仅安装Sql Server 2012不支持LocalDb。

  • I've published the app to the server, "Release" configuration, targeting the SQL Server 2012 database, using Migrations. 我已使用迁移功能将应用程序发布到服务器的“发布”配置中,以SQL Server 2012数据库为目标。 The db had already been created, empty, the user specified was dbo. 数据库已经创建,为空,指定的用户为dbo。 The error: 错误:

    One or more validation errors were detected during model generation: \\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'UserFile' has no key defined. 在模型生成期间检测到一个或多个验证错误:\\ tSystem.Data.Entity.Edm.EdmEntityType::EntityType'UserFile'没有定义键。 Define the key for this EntityType. 定义此EntityType的键。 [Repeats for each entity] \\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'UserFiles' is based on type 'UserProfile' that has no keys defined. [每个实体的重复] \\ tSystem.Data.Entity.Edm.EdmEntitySet:EntityType:EntitySet'UserFiles'基于未定义键的'UserProfile'类型。 [Repeats for each entity [每个实体的重复

  • I've generated a Script using Migration , send it to the server and then I executed it manually on the database. 我已经使用Migration生成了一个脚本 ,将其发送到服务器,然后在数据库上手动执行它。 I published the app to the server, "Release" configuration, targeting SQL 2012 and using Migrations (as database initializer). 我将该应用程序发布到服务器上,并以“ SQL Server 2012”为目标并使用Migrations(作为数据库初始化程序)进行了“发布”配置。 Same error. 同样的错误。

  • I've created an small ConsoleApplication that has a reference to my data access library. 我创建了一个小的ConsoleApplication,它引用了我的数据访问库。 The only thing it does is to initialize the context the same way that web app does (setting the Database.SetInitializer to use migrations and creating a context). 它唯一要做的就是用与Web应用程序相同的方式初始化上下文 (将Database.SetInitializer设置为使用迁移并创建上下文)。 I've sent it to the server and executed it. 我已经将其发送到服务器并执行了。 It runs with no problems! 它运行没有问题! The tables are correctly created in the database and no exception is thrown . 这些表已在数据库中正确创建,并且不会引发异常

It seems somehow my web application is broken. 似乎我的Web应用程序坏了。 I've got to find where. 我必须找到哪里。

Its frustrating. 它令人沮丧。 Why doesn't it recognize my model? 为什么无法识别我的模型? I've also used NLog to check if the OnModelCreating has been hit and it had. 我还使用NLog来检查OnModelCreating是否已命中和是否命中。 I believe that if no metadata information was found (stored in "__MigrationHistory" table, I think), the context should trust my database . 我认为,如果未找到元数据信息(我认为存储在“ __MigrationHistory”表中), 则上下文应信任我的数据库

It sounds like you're missing a primary key somewhere. 听起来好像您在某处缺少主键。

Make sure your entity has a key, make sure it's a "PROPERTY" (has get/set), and that it's "PUBLIC". 确保您的实体具有密钥,确保它是“属性”(具有获取/设置),并且它是“公共”。

Finally, try right clicking the model, and then select 'Update Model from Database" 最后,尝试右键单击模型,然后选择“从数据库更新模型”

Links: 链接:

Finally! 最后!

Out of some feeling, I've checked the application's AppPool settings and changed "Enable 32-bit Applications" from "false" to "true" and the web application was able to access the database. 出于某种感觉,我检查了应用程序的AppPool设置,并将“启用32位应用程序”从“ false”更改为“ true”,并且Web应用程序能够访问数据库。

I don't know why, though, but I will try to find out. 我不知道为什么,但是我会尝试找出答案。

UPDATE UPDATE

Apparently I'm not the first to find errors using EntityFramework + Windows Server 2008 R2 64bits + IIS 7.5 and the "Enable 32 bits" option: 显然,我不是第一个使用EntityFramework + Windows Server 2008 R2 64位+ IIS 7.5和“启用32位”选项发现错误的人:

Here Here 这里 这里

Nevertheless, in their case the symptoms were different. 但是,在他们的情况下,症状有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM