3

我对 EF 了解不多,但必须做一些错误修复。错误之一发生如下:

  • 使用获取父记录(EF LINQ 查询)ObjectContext
  • 更改一些属性
  • 保存更改

问题是Get parent record,更具体地说,只有父母的活动孩子

这是当前的黑客

var data =
    (from q in Context.Questions.Include("Status").Include("Category")
     where q.Id == id
     select q).SingleOrDefault();

var atts = Context.Answers.Where(a => a.qId == id && a.active); // 1
data.Answers.Clear(); // 2
foreach (var att in atts)
{
    data.Answers.Add(att); // 3
}

发生什么了:

  1. 从数据库中获取活动子记录
  2. 由于延迟加载,所有附件都是从数据库中获取的。然后立即清除该集合。(EF 跟踪将这些记录标记为“删除”?)
  3. 循环遍历所有活动记录并将它们再次添加到集合中(EF 跟踪将这些记录标记为“插入”?)

更新时出现以下异常:The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

我认为这是一个非常普遍的错误,因为 EF 对清除集合然后再次添加一些相同的记录感到困惑。

我的问题:我如何只获取活动的子记录并将它们置于“未更改”状态,以便 EF 在任何时候都无法决定删除并重新插入我的记录。显然我也不想在更新时丢失非活动记录。

不是答案(或者是吗?):经常在 SO 和 Google 上找到,但无法让它工作:

Context.ContextOptions.LazyLoadingEnabled = false;

var data =
    (from q in Context.Questions.Include("Status").Include("Category")
     where q.qId == id
     select new
     {
         Question = q,
         Answers = q.Answer.Where(a => a.active)
     }).ToArray().Select(q => q.Question).FirstOrDefault();

return data; // Does not contain the answers... :(
4

2 回答 2

3

您可以显式加载属性而不是加载它,然后清除它。这将防止在对象图中加载不需要的对象,因此在断开非活动实体时不会出现错误。

var data =
    (from q in Context.Questions.Include("Status").Include("Category")
     where q.Id == id
     select q).SingleOrDefault();

Context.Entry(data).Collection(b => b.Answers).Query()
    .Where(a => a.active)
    .Load();
于 2013-02-28T14:18:48.990 回答
0

调用data.Answers.Clear()是不够的,因为它只会删除您的问题和答案之间的关联。如果您还想删除这些答案,您也需要从上下文中删除它们。

foreach(var answer in data.Answers) {
  Context.DeleteObject(answer);
}

data.Answers.Clear();
于 2013-02-28T14:13:48.380 回答