gpt4 book ai didi

c# - Entity Framework 插入父子孙对象

转载 作者:行者123 更新时间:2023-11-30 18:20:09 24 4
gpt4 key购买 nike

我正在尝试插入一个具有 n 个子实体的父实体,该子实体还可以有 n 个自己的子实体。当我插入一个没有孙子的对象时,一切正常,但只要输入对象包含孙子,就会在 Context.SaveChanges() 上出现以下错误:

“操作失败:无法更改关系,因为一个或多个外键属性不可为空。对关系进行更改时,相关的外键属性设置为一个空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。"

家长:

 public class Parent : Entity
{
public Parent()
{
this.Children = new HashSet<Children>();
}
public virtual ICollection<Child> Children { get; set; }
}

child :

 public class Child : Entity
{
public Child ()
{
this.GrandChildren = new HashSet<GrandChild>();
}
public virtual ICollection<GrandChild> GrandChildren { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}

孙子:

 public class GrandChild : Entity
{
public int ChildId { get; set; }
public virtual Child Child { get; set; }
}

这是我的 DBContext:

    modelBuilder.Entity<Child>().ToTable("Children")
.HasRequired<Parent>(x => x.Parent);

modelBuilder.Entity<GrandChild>().ToTable("GrandChildren")
.HasRequired<Child>(y => y.Child);

modelBuilder.Entity<Parent>().ToTable("Parents")
.HasMany(z => z.Child)
.WithRequired(i => i.Parent);

然后最后我的插入如下,我根据另一个输入对象有条件地构建了一个新的亲子孙对象(我试图根据类似的亲子孙问卷保存问卷的初始状态对象层次结构):

public Parent Insert(List<AnotherObject> input)    
{
Parent parent = new Parent();

// Set parent attributes
foreach (var x in input)
{
Child child = new Child();
// Set child attributes
// EDIT: I also set an attribute based on the list of
// entities from the input
child.OtherObjectId = x.Id;
child.Parent = parent;

if (x.Children.Count > 0)
{
foreach (var y in x.Children)
{
GrandChild grandChild = new GrandChild();
// Set grandChild attributes

grandChild.Child = child;
child.GrandChildren.Add(grandChild);
}
}
parent.Children.Add(child);
}

Context.Parents.Add(parent);
Context.SaveChanges();
}

我已经多次检查了数据库和实体,所以我希望我的插入逻辑中存在某种缺陷。

编辑:这是输入列表(选定的)的来源,以防有助于确定某些内容:

        Random rand = new Random(DateTime.Now.ToString().GetHashCode());
var selected = diffParent.DiffChild.OrderBy(x => rand.Next()).Take(diffParent.AmountShown).ToList();
foreach (var q in selected)
{
var listOne = new List<DiffChild>();
var listTwo = new List<DiffChild>();
if (q.CountAttribute != null)
listOne = q.DiffChild.Where(c => c.Attribute == true).OrderBy(x => rand.Next()).Take((int)q.CountAttribute).ToList();
if (q.OtherCountAttribute != null)
listTwo = q.DiffChild.Where(d => d.Attribute != true).OrderBy(y => rand.Next()).Take((int)q.OtherCountAttribute).ToList();
q.DiffChildren = listOne.Concat(listTwo).ToList();
}

编辑:这个问题似乎源于所选列表,更具体地说,我尝试从完整列表中选择特定实体的 for 循环,如果我只传递这个:

var selected = diffParent.DiffChild.OrderBy(x => rand.Next()).Take(diffParent.AmountShown).ToList();

插入似乎没有问题。看来我一直在错误的地方寻找问题。

最佳答案

没错,我知道这将是一个固定的最大 3 深度,所以我采用了这个设计,但我会在未来牢记你所说的。在主题上,我设法通过将 diffParent 映射到 DTO 来解决这个问题,然后进行选择,然后将其映射回我传递给插入方法的实体列表。

关于c# - Entity Framework 插入父子孙对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37784301/

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