gpt4 book ai didi

c# - 在 EF 6 中更新子实体的正确方法是什么?

转载 作者:太空狗 更新时间:2023-10-29 23:14:10 25 4
gpt4 key购买 nike

必须有更好的方法来处理 EF 6 中的子级保存/更新。当然,这种重复只是我的失败。

实体

public partial class MyParentType
{
public MyParentType()
{
this.children = new HashSet<child>();
}

public int parentID { get; set; }

public virtual ICollection<child> children { get; set; }
}

添加/更新

public class MyRepository : IMyRepository
{
private readonly IErrorLogger _logger;
private readonly CorporateEntities _context;

public MyRepository(IErrorLogger logger)
{
_logger = logger;
_context = new CorporateEntities();
}

public void Update(IEnumerable<MyParentType> parents)
{
try
{
Add(parents.Where(x => x.parentID == 0));
var updatedData = parents.Where(x => x.parentID != 0);
foreach (var parent in updatedData)
{
var original = _context.MyParentTypes.FirstOrDefault(x => x.parentID == parent.parentID);
_context.Entry(original).CurrentValues.SetValues(parent);
UpdateChildren(parent);
}
_context.SaveChanges();
}
catch (Exception exception)
{
_logger.Error(exception.Message, exception);
}
}

public void Add(IEnumerable<MyParentType> parents)
{
if (parents == null)
return;
try
{
_context.MyParentTypes.AddRange(parents);
_context.SaveChanges();
}
catch (Exception exception)
{

_logger.Error(exception.Message, exception);
}
}

private void UpdateChildren(MyParentType parent)
{
try
{
AddChildren(parent.children.Where(x => x.childID == 0));
var updatedData = parent.children.Where(x => x.childID != 0);
foreach (var child in updatedData)
{
var original = _context.children.FirstOrDefault(x => x.childID == child.childID);
_context.Entry(original).CurrentValues.SetValues(child);
}
_context.SaveChanges();
}
catch (Exception exception)
{

_logger.Error(exception.Message, exception);
}
}

private void AddChildren(IEnumerable<child> references)
{
try
{
_context.children.AddRange(references);
_context.SaveChanges();
}
catch (Exception exception)
{

_logger.Error(exception.Message, exception);
throw;
}
}

}

我觉得我不应该重复这个或编写一个通用方法来处理这两种情况。我是否遗漏了 EF 文档中的某些内容,我可以在其中使用父实体更新子实体?

最佳答案

我建议您使用 GraphDiff .有了这个library您的 Update 方法如下所示:

 public void Update(IEnumerable<MyParentType> parents)
{
try
{
Add(parents.Where(x => x.parentID == 0));
var updatedData = parents.Where(x => x.parentID != 0);
foreach (var parent in updatedData)
{
_context.UpdateGraph(parent, map => map.OwnedCollection(p => p.children));
}
_context.SaveChanges();
}
catch (Exception exception)
{
_logger.Error(exception.Message, exception);
}
}

这样你就不用担心管理 child 的状态。

如果你不想使用GraphDiff,那么你需要手动管理children的状态:

 public void Update(IEnumerable<MyParentType> parents)
{
try
{
foreach (var parent in parents)
{
if(parent.Id==0)
{
_context.MyParentTypes.Add(parent);
}
else
{
//When you change the state to Modified all the scalar properties of the entity will be marked as modified
_context.Entry(parent).State = EntityState.Modified;

foreach(var child in parent.children)
{
context.Entry(child).State =child.Id>0? EntityState.Modified:EntityState.Added;
}
}
}

_context.SaveChanges();
}
catch (Exception exception)
{
_logger.Error(exception.Message, exception);
}
}

关于c# - 在 EF 6 中更新子实体的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29351401/

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