1

我刚刚从 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. Entity Framework 4.3.1 版本有bug?
  2. 我的代码在 4.0.0 下工作而在 OnModelCreating 方法中没有额外两行的事实可能是由于在 4.0.0 中没有进行检查,而现在在 4.3.1 中进行了检查?
  3. 我需要在我的配置/代码中添加一些额外的东西,或者我缺少其他东西来使这项工作在 4.3.1 下再次工作?

任何人都可以为我阐明这一点吗?它让我发疯!非常感谢您在这方面的时间。亲切的问候史蒂夫

4

1 回答 1

2

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

  • ModelBuilder 在 4.1 RTM 之前重命名为 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")
    {
    }
}

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

于 2012-04-22T16:19:10.250 回答