C# 实体框架,所需引用的奇怪行为,延迟加载

C# 实体框架,所需引用的奇怪行为,延迟加载,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,这适用于实体框架4(4.3.1)和5 我有一个用户类(与我的实体框架MembershipProvider一起使用)。为了简化,我删除了一些属性。实际用户来自MVCBootstrap项目,因此它与其他类不属于同一程序集 public class User { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } [Required] [StringLeng

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

我有一个用户类(与我的实体框架MembershipProvider一起使用)。为了简化,我删除了一些属性。实际用户来自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; }
}
然后创建数据库上下文(用户的数据库集位于MembershipDbContext中):

公共类MyContext:MVCBootstrap.EntityFramework.MembershipDbContext{
public MyContext(String-connectString):base(connectString){}
公共数据库集新闻项{get;set;}
}
在创建数据库时,运行此代码将出现以下异常:

在表“WebShop”上引入外键约束“FK_dbo.WebShop_dbo.User_LastEditor_Id”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束。 无法创建约束。请参阅前面的错误

因此,我更改数据库上下文:

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());
    }
}
公共类MyContext:MVCBootstrap.EntityFramework.MembershipDbContext{
public MyContext(String-connectString):base(connectString){}
公共数据库集新闻项{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder){
基于模型创建(modelBuilder);
modelBuilder.Configurations.Add(新的NewsItemConfiguration());
}
}
以及此配置:

public class NewsItemConfiguration : EntityTypeConfiguration<NewsItem> {
    public NewsItemConfiguration() {
        HasRequired(n => n.Author).WithOptional();
        HasRequired(n => n.LastEditor).WithOptional();
    }
}
公共类NewsItemConfiguration:EntityTypeConfiguration{ 公共NewsItemConfiguration(){ HasRequired(n=>n.Author).WithOptional(); HasRequired(n=>n.LastEditor).WithOptional(); } } 或者这是错误的

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

但是,然后我从上下文中获取10个最新的新闻项,并开始将它们加载到视图模型中,其中一部分是访问新闻项的Author属性。执行此操作的控制器将永远无法加载,并且会在很长很长时间后出现故障。在调试模式下运行时,我在这段代码中遇到一个异常:
this.AuthorId=newsItem.Author.Id,那么我得到的例外是:

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

可能是一些简单而愚蠢的事情我做错了,我确信我在几个网站上运行过类似的代码,所以。。这是什么原因造成的?我的模型有错吗?是数据库上下文还是这部分

在表“WebShop”上引入外键约束“FK_dbo.WebShop_dbo.User_LastEditor_Id”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束。无法创建约束。请参阅前面的错误

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

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

想想看。。。这就是你想要的吗?似乎您希望取消作者和LastEditor与新闻项的关联,而不是将其从数据库中删除

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

this.AuthorId = newsItem.Author.Id;
但在我看来,你应该以另一种方式完成任务

newsItem.Author = myAuthorInstance;
或者,如果您在模型中包含外键属性,并且之前保存了author实例并具有Id:

newsItem.AuthorId = myAuthorInstance.Id; 

如果您共享生成的DB模式(相关部分),则更容易诊断问题。

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

公共类NewsItemConfiguration:EntityTypeConfiguration{ 公共NewsItemConfiguration(){ HasRequired(n=>n.Author).WithMany(); HasRequired(n=>n.LastEditor).WithMany(); } }
代码段
this.AuthorId=newsItem.Author.Id
位于视图模型中,而不是POCO中,因此这将在视图模型中存储作者id。当我删除新闻项时,我不想删除作者。如果是在视图模型中,那么您不可能在该行中得到与数据库相关的错误…我确定这是延迟抓取,还有什么可能?是的,当然,不幸的是,我仍然在“引入外键约束”等中得到相同的错误。
newsItem.AuthorId = myAuthorInstance.Id; 
public class NewsItemConfiguration : EntityTypeConfiguration<NewsItem> {
    public NewsItemConfiguration() {
        HasRequired(n => n.Author).WithMany();
        HasRequired(n => n.LastEditor).WithMany();
    }
}