0

这适用于实体框架 4 (4.3.1) 和 5。

我有一个 User 类(与我的 Entity Framework MembershipProvider 一起使用)。为了简化,我删除了一些属性。实际的 User 来自 MVCBootstrap 项目,因此它与其他类不属于同一程序集。

public class User {
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    [Required]
    [StringLength(256)]
    public String Username { get; set; }
}

然后我有这堂课:

public class NewsItem {
    public Int32 Id { get; set; }
    [Required]
    [StringLength(100)]
    public String Headline { get; set; }
    [Required]
    public virtual User Author { get; set; }
    [Required]
    public virtual User LastEditor { get; set; }
}

然后我创建数据库上下文(用户的 DbSet 在 MembershipDbContext 中):

public class MyContext : MVCBootstrap.EntityFramework.MembershipDbContext {
    public MyContext(String connectString) : base(connectString) { }
    public DbSet<NewsItem> NewsItems { get; set; }
}

在创建数据库时运行此代码会给我这个异常:

在表“WebShop”上引入 FOREIGN KEY 约束“FK_dbo.WebShop_dbo.User_LastEditor_Id”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束。请参阅以前的错误。

所以我改变了数据库上下文:

public class MyContext : MVCBootstrap.EntityFramework.MembershipDbContext {
    public MyContext(String connectString) : base(connectString) { }
    public DbSet<NewsItem> NewsItems { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new NewsItemConfiguration());
    }
}

而这个配置:

public class NewsItemConfiguration : EntityTypeConfiguration<NewsItem> {
    public NewsItemConfiguration() {
        HasRequired(n => n.Author).WithOptional();
        HasRequired(n => n.LastEditor).WithOptional();
    }
}

或者这是错的?

无论如何,当我运行代码时,会创建数据库,并且数据库看起来还可以(查看外键约束等)。

但是,然后我从上下文中获取 10 个最新的 NewsItem,并开始将它们加载到视图模型中,其中一部分是访问 NewsItem 上的 Author 属性。执行此操作的控制器需要永远加载,并且在很长一段时间后会失败。在调试模式下运行时,我在这段代码中得到一个异常:this.AuthorId = newsItem.Author.Id;,然后我得到的异常是这样的:

发生关系多重性约束违规:EntityReference 不能有多个相关对象,但查询返回多个相关对象。这是一个不可恢复的错误。

这可能是我做错了一些简单而愚蠢的事情,我确定我已经在多个站点上运行了类似的代码,所以..是什么原因造成的?我的模型错了吗,是数据库上下文,还是?

4

2 回答 2

0

这部分

在表“WebShop”上引入 FOREIGN KEY 约束“FK_dbo.WebShop_dbo.User_LastEditor_Id”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束。请参阅以前的错误。

实际上是 SQL Server 问题(以及许多其他 RDBMS 的问题)。解决多个级联路径是一个复杂的问题,SQL Server 决定只是放弃而不尝试。看

外键约束可能导致循环或多个级联路径?

您试图将模型配置为在删除 NewsItem 时删除子 Author 和 LastEditor 对象。SQL Server 不会这样做。

想一想……这就是你想要的吗? 看来您希望取消 Author 和 LastEditor 与 NewsItem 的关联,而不是从数据库中删除它们。

您的对象模型需要 NewsItem 和 Author 之间以及 NewsItem 和 LastEditor 之间的 1:1 关系。我不确定在代码中指的是什么

this.AuthorId = newsItem.Author.Id;

但在我看来,你应该反过来做任务,例如

newsItem.Author = myAuthorInstance;

或者,如果您在模型中包含外键属性,并且您之前保存了作者实例并具有 Id:

newsItem.AuthorId = myAuthorInstance.Id; 

如果您共享生成的数据库架构(相关部分),这将更容易诊断问题。

于 2012-09-21T06:55:32.577 回答
0

用户可以是多个新闻项目的作者。此外,用户可以是多个新闻项目的编辑。
因此,关系必须是“一对多”:

public class NewsItemConfiguration : EntityTypeConfiguration<NewsItem> {
    public NewsItemConfiguration() {
        HasRequired(n => n.Author).WithMany();
        HasRequired(n => n.LastEditor).WithMany();
    }
}
于 2012-09-21T07:09:27.007 回答