我有一个基于ASP.Net MVC 6 / ASP.Net Core 1.0的应用程序,它通过Web API公开CRUD方法。
我正在使用Entity Framework 7.0.0-rc1,我计划将所有内容迁移到EF Core 1.0 / ASP.Net Core 1.0但尚未完成此操作。
这是一个模型类型的片段,它引起了我的设计问题:
public class ParentEntity
{
public int Id { get; set; }
public virtual ICollection<ChildEntity> ChildCollection { get; set; } = new ChildCollection();
}
public class Child
{
public int Id { get; set; }
public virtual ParentEntity ParentEntity { get; set; }
public int? ParentEntityId { get; set; }
}
在我的ApplicationContext
类中正确确保了所有关系,并且所有CRUD操作都按预期工作,包括保存ParentEntity时子实体的添加和更新。
例如,这是我通过API公开的Save方法:
// On some web API Save method :
[HttpPost]
public JsonResult Save(ParentEntity entity)
{
if (entity.Id > 0) _context.Update(entity);
else _context.Add(entity);
var result = _context.SaveChanges();
return Json(result);
}
传递给save方法的实体来自我的AngularJS后端。只要添加或修改了子实体,一切都按预期工作。
现在让我们想象后端收到一个ParentEntity
加载了两个名为ChildEntity
和A
的{{1}}。
现在在后端我删除B子实体并将其发布到save方法。
后端会保存所收到数据的更改:所有更新都会保留在B
和ParentEntity
A上。
但是B ChildEntity
仍然存在于数据存储区中,这似乎是合乎逻辑的,因为没有迹象表明如何处理它。
所以我的问题是,因为在我看来这是一个非常常见的情况:我该如何处理?
我想象存储子集合的某个地方,保存更改,重新加载根实体,比较集合,确定应删除哪些,然后将其删除,但对我来说似乎相当困难和肮脏。还有更好的方法吗?
答案 0 :(得分:1)
答案 1 :(得分:0)
根据上面MSDN博客文章中解释的一些提示,我已经通过它的基类在每个实体上实现了一个客户端状态字段:
public enum ObjectState
{
Unchanged = 0,
Added = 1,
Modified = 2,
Deleted = 3
}
public interface IObjectWithState
{
ObjectState ClientState { get; set; }
}
public abstract class BaseEntity : IBaseEntity, IPrimaryKey
{
public int Id { get; set; }
public string Name { get; set; }
[NotMapped]
public bool IsNew => Id <= 0;
[NotMapped]
public ObjectState ClientState { get; set; } = ObjectState.Unchanged;
}
每当从客户端的集合中删除子实体时,我会将其保留在集合上,并将其标记为已删除。
然后我只需要在服务器端处理它:
_context.ChildEntityCollection.RemoveRange(
entity.ChildCollection.Where(c => c.ClientState == ObjectState.Deleted).ToList()
);
_context.SaveChanges();
我在每个实体上实现了整个枚举,但是目前我只使用Deleted值,并且只通过关系。到目前为止,不需要其他值或根实体上的任何值。