gpt4 book ai didi

c# - 如何解决 EF 5 Code First 中组合的一对一和一对多关系

转载 作者:行者123 更新时间:2023-11-30 17:07:12 28 4
gpt4 key购买 nike

我使用 Entity Framework 5 和 Code First。

我有两个域实体 QuestionAnswer 用于测验应用程序。一个问题有几个可能的答案。一个问题也有一个正确答案,它应该引用一个可能的答案。我在 to 实体之间结合一对多和一对一关系时遇到了一些问题。请参阅Q1Q2

这是实体的代码:

public class Question
{
public virtual int Id { get; set; }
[Required]
public virtual string Text { get; set; }

[InverseProperty("Question")]
public virtual ICollection<Answer> PossibleAnswers { get; set; }
public virtual Answer CorrectAnswer { get; set; }

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual DateTime? UpdateStamp { get; set; }
}

public class Answer
{
public virtual int Id { get; set; }
[Required]
public virtual string Text { get; set; }

[ForeignKey("QuestionId")]
public virtual Question Question { get; set; }
public virtual int QuestionId { get; set; }
}

Q1:我应该怎么做才能在一次往返数据库(例如一次调用上下文 SaveChanges)中插入问题对象和引用的答案(通过属性 PossibleAnswers)?在不先添加答案的情况下保存问题和答案时出现的错误是:

Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.

为了解决这个问题,我尝试了以下方法,使用流畅的 API 来获取要在问题之前添加的答案,而这一切只需一次调用 objectcontexts SaveChanges:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Question>()
.HasOptional(q => q.CorrectAnswer)
.WithRequired();

base.OnModelCreating(modelBuilder);
}

但是,这导致我犯了另一个错误:

Conflicting changes detected. This may happen when trying to insert multiple entities with the same key.

第一季度的流畅 API 方法是否走在正确的道路上?为什么会出现错误消息?

Q2:删除问题时我意识到会出现错误,因为问题不能在答案之前删除,反之亦然。我该如何解决这个问题?例如,是否应该在 Question.CorrectAnswer 和 Question.PossibleAnswers 上指定 WillCascadeOnDelete?

最佳答案

对于您的问题 Q1 和 Q2,您将需要两次往返/两次调用 SaveChanges(除了使用存储过程解决问题之外)。

Q1:第一个调用将 Question.CorrectAnswer 设置为 null,第二个调用将 CorrectAnswer 设置为存储的答案之一.

问题 2:第一次调用将 Question.CorrectAnswer 设置为 null,第二次调用删除了 Question 和启用级联删除的相关答案.

如果您不太担心两次往返,而是更担心与两次 SaveChanges 调用相对应的两次​​交易,您可以包装整个操作,包括两次 SaveChanges 调用成一个单一的手动交易。 (示例:EF: How do I call SaveChanges twice inside a transaction?)

关于一对一关系:尽管从业务角度来看 CorrectAnswer 的关系是一对一的,但很难甚至不可能将其建模为一对一与 EF 的关系。

问题在于 EF 不支持外键一对一关联,即外键(CorrectAnswerId 左右)具有唯一约束的关系。它仅支持共享主键一对一关联,其中依赖项 (Question) 的主键是主体 (Question.CorrectAnswer) 的外键 ( 回答) 同时。您的 Fluent 代码就是这种共享主键关联的配置。但这意味着唯一有效的 CorrectAnswer 是与 Question 具有相同主键值的 Answer。虽然这在理论上是可能实现的(您的 Answer 表比 Question 表有更多的记录),但很可能需要不使用自动生成的键,而是手动提供键。将 CorrectAnswers 从一个 Answer 更改为另一个是不可能的。因此,在我看来,共享主键不适合您的模型。

更好的解决方案是删除 Fluent 映射。结果将是与 Question 表中的 CorrectAnswer 的可为空外键的一对多关系。从数据库的角度来看,这意味着相同的 Answer 可以是许多 QuestionCorrectAnswer,这在您的业务逻辑中可能是无稽之谈,因为每个问题都有它自己独特的一组答案和两个问题永远不会共享相同的答案。但是您可以通过不向 Answer 添加反向集合属性(如 QuestionsThisIsTheCorrectAnswerFor)来从您的业务逻辑中“隐藏”这种一对多关系。虽然它没有完美地模拟业务约束,但它在技术上没有问题。

有关与 EF 一对一关系的困难的更多信息,请参阅以下博客文章:

关于c# - 如何解决 EF 5 Code First 中组合的一对一和一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14751898/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com