EF从4.0.0升级到4.3.1会导致奇怪的错误

时间:2012-04-21 21:59:24

标签: entity-framework

我刚刚从EF 4.0.0升级到EF 4.3.1。 我在Windows XP上使用Visual Studio 2010 Ultimate更新到最新版本并应用了所有Windows更新/补丁。我正在使用的数据库引擎是SQL Server 2008 R2 Developers Edition。 以下代码在EF 4.0.0下完美运行,但不在EF 4.3.1下运行。

public class ItemBase
{
    public DateTime Created { get; set; }
    public int CreatedByUserID { get; set; }
    public DateTime LastModified { get; set; }
    public int LastModifiedByUserID { get; set; }

    public User CreatedBy { get; set; }
    public User LastModifiedBy { get; set; }

    public ItemBase()
    {
        CreatedByUserID = -1;
        LastModifiedByUserID = -1;
        CreatedBy = null;
        LastModifiedBy = null;
    }
}


public class User : ItemBase
{
    public int UserID { get; set; }
    public string LoginName { get; set; }
    public string Password { get; set; }
    public string EmailAddress { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string DisplayName { get; set; }

    public User() : base()
    {
        UserID = -1;
        LoginName = String.Empty;
        Password = String.Empty;
        EmailAddress = String.Empty;
        Firstname = String.Empty;
        Lastname = String.Empty;
        DisplayName = String.Empty;
    }
}


protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<User>().Property(u => u.UserID).HasDatabaseGenerationOption(DatabaseGenerationOption.Identity);
}

唯一改变的是我正在使用的实体框架版本。 我检查了引用等,一切都按预期进行。

从上面的代码中可以看出,User类继承自ItemBase,而ItemBase又引用了User实例。底层User表包含User类和ItemBase类的所有属性(两个导航属性public User CreatedBy {get; set;}和public User LastModifiedBy {get; set;}除外) 在4.0.0下运行此代码,一切都按预期工作,而不是单个问题或任何问题。

但是,当我在4.3.1下运行相同的代码(没有任何改变,包括我正在使用的数据库)时,我收到以下错误:

无法确定”用户“和”用户“类型之间关联的主要结束。必须使用关系流畅API或数据注释显式配置此关联的主要末端。

然后我将以下两行添加到OnModelCreating方法中:

modelBuilder.Entity<User>().HasRequired(u => u.CreatedBy).WithMany().HasForeignKey(k => k.CreatedByUserID);
modelBuilder.Entity<User>().HasRequired(u => u.LastModifiedBy).WithMany().HasForeignKey(k => k.LastModifiedByUserID);

然后我得到了这些奇怪的错误:

提供商未返回ProviderManifestToken字符串。

建立与SQL Server的连接时发生与网络相关或特定于实例的错误。找不到服务器或无法访问服务器。验证实例名称是否正确以及SQL Server是否配置为允许远程连接。 (提供程序:SQL网络接口,错误:26 - 查找指定的服务器/实例时出错)

我还注意到输出窗口中的这些错误的加载和加载: “ System.Data.dll中出现'System.Data.SqlClient.SqlException'类型的第一次机会异常

然而,这些错误似乎有点像红鲱鱼,因为数据库很好,可用,连接字符串也很完美。如果我随后撤消对OnModelCreating方法的更改,我再次得到原始错误,所以我不相信我得到的错误消息实际上反映了此处发生的潜在问题。

因此,基于所有这些,我得出以下结论:

  1. 实体框架版本4.3.1中存在错误?
  2. 我的代码在4.0.0下运行而没有额外的两行 在OnModelCreating方法可能是由于检查没有 在4.0.0中制作,现在随后在4.3.1中制作?
  3. 我需要在配置/代码中添加额外的东西,或者我 错过了其他的东西,以便在4.3.1下重新开始工作?
  4. 任何人都可以为我阐明这一点吗?它让我疯了! 非常感谢您的时间。 亲切的问候 史蒂夫

1 个答案:

答案 0 :(得分:2)

看起来您一直在使用EF 4.1的预发布版本。可能是CTP4或CTP5。这很明显是因为:

  • 在4.1 RTM
  • 之前将ModelBuilder重命名为DbModelBuilder
  • DatabaseGenerationOption已重命名为DatabaseGeneratedOption
  • 您看到的例外是在EF 4.1为RTM之前引入的

鉴于此,我不是100%确定使用您正在使用的预发布版本创建的模型。使用4.1及更高版本,两个导航属性被检测为彼此的反转,Code First尝试在用户和用户之间建立1:1的关系。 Code First无法确定这种关系的原则,而不是猜测它会要求你提供它。

但是,看看你的模型很明显,这不是你想要的。你似乎更有可能想要两个1:*单向导航道具 - 一个用于CreatedBy,一个用于LastModifiedBy。这是您在OnModelCreating调用中设置的内容。

对类名称进行更改以匹配4.1 / 4.3以及添加到OnModelCreating的代码,您的代码在EF 4.3.1上可以正常使用。

关于无法建立连接,你说连接字符串是正确的,在这种情况下,它必须是EF没有找到它的情况。假设它在你的app.config中,那么你需要将它的名称传递给DbContext构造函数。例如:

public class MyContext : DbContext
{
    public MyContext()
     : base("name=MyConnectionStringName")
    {
    }
}

如果您以其他方式使用连接字符串,那么我们需要更多详细信息。