如何在 EF Core 中深入 clone/copy
How to deep clone/copy in EF Core
我想做的是 duplicate/copy 我的 School
对象及其在 EF Core
中的所有 children/associations
我有如下内容:
var item = await _db.School
.AsNoTracking()
.Include(x => x.Students)
.Include(x => x.Teachers)
.Include(x => x.StudentClasses)
.ThenInclude(x => x.Class)
.FirstOrDefaultAsync(x => x.Id == schoolId);
我一直在阅读有关深度克隆的文章,看来我应该 能够只添加实体...几乎就是下一行。
await _db.AddAsync(item);
那么 EF 应该足够聪明,可以将该实体添加为新实体。但是,马上我就遇到了一个冲突,上面写着 "the id {schoolId} already exists" 并且不会插入。即使我重置了我试图添加的新项目的 ID,我仍然与学校项目的 associations/children 的 ID 发生冲突。
有没有人熟悉这个以及我可能做错了什么?
我遇到了同样的问题,但就我而言,ef core 足够聪明,即使具有现有 ID,也可以将它们保存为新实体。然而,在意识到这一点之前,我只是为所有项目创建了一个复制构造函数,创建了一个仅包含所需属性的本地任务变量并返回了副本。
Remove certain properties from object upon query EF Core 2.1
我也有同样的问题,但在我的情况下 EF 核心抛出异常 "the id already exists"。
按照@Irikos 的回答,我创建了克隆我的对象的方法。
这是例子
public class Parent
{
public int Id { get; set; }
public string SomeProperty { get; set; }
public virtual List<Child> Templates { get; set; }
public Parent Clone()
{
var output = new Parent() { SomeProperty = SomeProperty };
CloneTemplates(output);
return output;
}
private void CloneTemplates(Parent parentTo, Child oldTemplate = null, Child newTemplate = null)
{
//find old related Child elements
var templates = Templates.Where(c => c.Template == oldTemplate);
foreach (var template in templates)
{
var newEntity = new Child()
{
SomeChildProperty = template.SomeChildProperty,
Template = newTemplate,
Parent = parentTo
};
//find recursivly all related Child elements
CloneTemplates(parentTo, template, newEntity);
parentTo.Templates.Add(newEntity);
}
}
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
public int? TemplateId { get; set; }
public virtual Child Template { get; set; }
public string SomeChildProperty { get; set; }
}
然后我只调用 DbContext.Parents.Add(newEntity)
和 DbContext.SaveChanges()
这对我有用。也许这对某人有用。
我想做的是 duplicate/copy 我的 School
对象及其在 EF Core
我有如下内容:
var item = await _db.School
.AsNoTracking()
.Include(x => x.Students)
.Include(x => x.Teachers)
.Include(x => x.StudentClasses)
.ThenInclude(x => x.Class)
.FirstOrDefaultAsync(x => x.Id == schoolId);
我一直在阅读有关深度克隆的文章,看来我应该 能够只添加实体...几乎就是下一行。
await _db.AddAsync(item);
那么 EF 应该足够聪明,可以将该实体添加为新实体。但是,马上我就遇到了一个冲突,上面写着 "the id {schoolId} already exists" 并且不会插入。即使我重置了我试图添加的新项目的 ID,我仍然与学校项目的 associations/children 的 ID 发生冲突。
有没有人熟悉这个以及我可能做错了什么?
我遇到了同样的问题,但就我而言,ef core 足够聪明,即使具有现有 ID,也可以将它们保存为新实体。然而,在意识到这一点之前,我只是为所有项目创建了一个复制构造函数,创建了一个仅包含所需属性的本地任务变量并返回了副本。
Remove certain properties from object upon query EF Core 2.1
我也有同样的问题,但在我的情况下 EF 核心抛出异常 "the id already exists"。 按照@Irikos 的回答,我创建了克隆我的对象的方法。
这是例子
public class Parent
{
public int Id { get; set; }
public string SomeProperty { get; set; }
public virtual List<Child> Templates { get; set; }
public Parent Clone()
{
var output = new Parent() { SomeProperty = SomeProperty };
CloneTemplates(output);
return output;
}
private void CloneTemplates(Parent parentTo, Child oldTemplate = null, Child newTemplate = null)
{
//find old related Child elements
var templates = Templates.Where(c => c.Template == oldTemplate);
foreach (var template in templates)
{
var newEntity = new Child()
{
SomeChildProperty = template.SomeChildProperty,
Template = newTemplate,
Parent = parentTo
};
//find recursivly all related Child elements
CloneTemplates(parentTo, template, newEntity);
parentTo.Templates.Add(newEntity);
}
}
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
public int? TemplateId { get; set; }
public virtual Child Template { get; set; }
public string SomeChildProperty { get; set; }
}
然后我只调用 DbContext.Parents.Add(newEntity)
和 DbContext.SaveChanges()
这对我有用。也许这对某人有用。