gpt4 book ai didi

c# - EF 5.0 Code First 将新的 child 添加到现有的 parent

转载 作者:行者123 更新时间:2023-11-30 22:24:13 25 4
gpt4 key购买 nike

概述:我正在使用 Code First 和 EF 5.0 开发 MVC ASP.Net 应用程序。我有两个表:Scripts 和 ScriptItems。一个脚本可以有多个 ScriptItem。 ScriptItems 也是分层的。 ScriptItems 可以选择性地属于彼此,但是谢天谢地,这种关系只有 1 层深。这种关系由 ScriptItem.ParentId 指示。

问题:使用 ScriptItems 创建一个新的脚本条目工作得很好。当我尝试将 ScriptItems 添加到现有脚本时,问题就出现了。如果我尝试添加没有 ParentId 的 ScriptItems,一切正常。一旦我尝试添加具有 ParentId 的 ScriptItems,我就会收到 FK 违规异常。

详细信息:

脚本类:

public class Script
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Type { get; set; }
[ForeignKey("ProcessorId")]
public Processor Processor { get; set; }
public int ProcessorId { get; set; }
public string Owner { get; set; }
public DateTime Created { get; set; }
public bool Public { get; set; }

public List<ScriptItem> Items { get; set; }
public List<ScriptRun> Runs { get; set; }

public Script()
{
Items = new List<ScriptItem>();
Created = DateTime.Now;
}
}

ScriptItem 类:(为简洁起见被截断)

 public class ScriptItem
{
[Key]
public int Id { get; set; }

[ForeignKey("ParentId")]
public ScriptItem Parent { get; set; }
public int? ParentId { get; set; }

public Script Script { get; set; }
[ForeignKey("Script")]
public int ScriptId { get; set; }

添加脚本项的函数:

private void addToScript(ScriptModel model, List<int> ids)
{
Script script = scriptRepository.GetScriptWithItems(model.ScriptId);
List<History> historyItems = historyRespository.History.Where(h => ids.Contains(h.Id)).ToList();

ScriptItem lastScriptItem = script.Items.OrderByDescending(item => item.SortIndex).FirstOrDefault();
int topSortIndex = lastScriptItem == null ? 0 : lastScriptItem.SortIndex;

if (script != null)
{
List<ScriptItem> newItems = new List<ScriptItem>();
Mapper.CreateMap<History, ScriptItem>();
foreach (History h in historyItems)
{
ScriptItem scriptItem = new ScriptItem();
Mapper.Map(h, scriptItem); //Populate new ScriptItem from History entry
scriptItem.SortIndex = ++topSortIndex;
scriptItem.ScriptId = model.ScriptId;
scriptItem.Script = script;

//Only add an entry if it is NOT the parent of another entry. Otherwise, EF will duplicate the Parent entries
if (!historyItems.Any(his => his.ParentId == h.Id))
newItems.Add(scriptItem);
}
scriptRepository.AddScriptItems(newItems);
}
}

最后是 scriptRepository.AddScripItems():

public void AddScriptItems(List<ScriptItem> items)
{
items.ForEach(item => context.Entry(item).State = System.Data.EntityState.Added);
context.SaveChanges();
}

考虑我将两个 ScriptItem A 和 B 添加到现有脚本的场景。 A 是 B 的父级。当我运行 SQL Server 跟踪时,我看到尝试插入父级记录 A,但 ScriptId 为 0,因此出现 FK 违规异常。不知道为什么 ScriptId 是 0。ScriptId 在 ScriptItems 上设置正确,我用调试器验证了这一点。

我没有包含插入新脚本和项目的函数,因为它与上面的 addToScript 函数非常相似。它工作正常。但如果有人想看,我也可以添加。

比我聪明的人有什么想法吗?谢谢!

最佳答案

不知道是什么原因造成的。但我认为将新的 ScriptItem 添加到 script.Items 而不是设置它们的所有者脚本可能会有所帮助,即替换

scriptItem.ScriptId = model.ScriptId;
scriptItem.Script = script;

通过

script.Items.Add(scriptItem);

另一个优点是您不必再手动更改它们的状态:更改跟踪器知道何时将新项目添加到跟踪集合中。我什至想知道在您的脚本中是否有必要这样做,因为设置 Script 也应该足够了。

也许设置script ScriptId 改变状态过多地干扰了EF自己的逻辑并把它偏离轨道。

关于c# - EF 5.0 Code First 将新的 child 添加到现有的 parent ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12884382/

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