我有这样的模型
public class Question
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public Answer Answer { get; set; }
public List<Variant> Variants { get; set; }
public string CorrectVariantId { get; set; }
public Variant CorrectVariant { get; set; }
}
public class Variant
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public string QuestionId { get; set; }
public Question Question { get; set; }
}
// mapping
modelBuilder.Entity<Question>()
.HasOne(q => q.CorrectVariant)
.WithOne(v => v.Question)
.HasForeignKey<Question>(q => q.CorrectVariantId);
modelBuilder.Entity<Variant>()
.HasOne(v => v.Question)
.WithMany(a => a.Variants)
.OnDelete(DeleteBehavior.Cascade);
在我从 EF RC1
升级到 RTM
之前,它工作得很好。但现在它抛出:
System.InvalidOperationException:无法在“Question.Variants”和“Variant.Question”之间创建关系,因为“Question.CorrectVariant”和“Variant.Question”之间已经存在关系。导航属性只能参与单个关系。
如果不从 Question
模型中删除 Variants
属性,是否有任何解决此问题的方法?
最佳答案
给出的两个例子已经让我完成了一部分,但我想要一个集合和一个相同对象类型的单个项目,因此我的模型上有同一个表,就像在原始问题中一样。我试图在下面提供一个适用于 .NET Core 2.2 的简单示例:
public class ParentModel
{
public int Id { get; set; }
// Id for single instance navigation property
public int? ChildModelId { get; set; }
// Single instance navigation property to ChildTable, identified by ChildModelId property as foreign key
public virtual ChildModel ChildModel { get; set; }
// Collection navigation property to ChildTable with identified by ParentId property
public virtual ICollection<ChildModel> ChildModels { get; set; }
}
public class ChildModel
{
public int Id { get; set; }
// Id for ParentModel property back to ParentTable
public int ParentId { get; set; }
// Single instance navigation property to ParentTable, identified by ParentId property as foreign key
public virtual ParentModel ParentModel { get; set; }
}
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ParentModel>()
.ToTable("ParentTable");
// Configure collection of ChildModels (ParentTable to ChildTable/one-to-many relationship)
builder.Entity<ParentModel>()
.HasMany(t => t.ChildModels)
.WithOne(t => t.ParentModel)
.HasForeignKey(t => t.ParentId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<ChildModel>()
.ToTable("ChildTable");
// Configure single ChildModel navigation property on ParentModel (one-to-one relationship)
builder.Entity<ParentModel>()
.HasOne(t => t.ChildModel)
.WithOne()
.HasForeignKey(typeof(ParentModel), nameof(ParentModel.ChildModelId))
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
}
}
避免Navigation properties can only participate in a single relationship.
错误的关键是将导航属性配置回父表只一次。我们使用 .WithOne(t => t.ParentModel)
为 ParentTable 上的 ChildModels
集合配置它。然后,我们不必通过调用空的 .WithOne()
来为后续关系配置关系的另一端,因为如果我们再次配置它(例如 .WithOne(t => t.ParentModel)
) 会报错。
导航属性上的 virtual
修饰符也允许 lazy loading .
关于c# - EF7(核心)中同一个表的多个关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38520695/