【问题标题】:Disconnected Complex Graph With Disconnected Child Entities具有断开子实体的断开复杂图
【发布时间】:2013-11-15 20:22:21
【问题描述】:

我有一个包含子实体集合的复杂图。父子实体之间的关系是一对多关系并且具有独立关联。我知道如果没有我想避免的手动同步,我就无法保留我的图表。我发现GraphDiff 解决方案很有前景,我开始探索它,但我无法实现我的目标,因为我的场景有些特殊。这个问题完全与 GraphDiff 有关,但我也欢迎其他解决方案。

public class person
{
    public virtual int Id {get; set;} //primary key
    public virtual string Name {get; set;}
    public virtual ICollection<Car> Cars {get; set;}
 }
public class Car
{
    public virtual int PersonId {get; set;} // is a foreign key 
    public virtual Datetime BoughtDate {get; set;}   // this property and above mentioned foreign key together makes a primary key in database

    public virtual DateTime InsuraceStartDate {get; set;}
    public virtual DateTime InsuraceExpiryDate {get; set;}
    public virtual DateTime LastServiceDate {get; set;}
}

在任何给定时间,我的 Person.Cars 集合都可能包含 1.一个新的汽车对象。 2. 具有更新值的现有汽车对象。(保险或服务日期)。

Person 上的 Id 属性和 Car 上的 PersonId 将为 0。

    Person _person = GetPersonToAddOrUpDate();
     int id =   _person.id; //id will be 0.

此时我们不确定我们收到的对象是否需要添加或更新。子实体(汽车)上的 PersonId 也将为 0。现在如果我们调用。

     Context.UpdateGraph(_person, m => m.OwnedCollection(x => x.Cars)); 
  throws exception at FindEntityMatching(entity). 

为了克服这个问题,我必须更新 person 的 Id 属性。

     var dbPersonId  = Context.Single<Person>(x => x.Name == _person.Name).Id;
    _person.id = dbPersonId != null ? dbPersonId : 0;
     Context.UpdateGraph(_person, m => m.OwnedCollection(x => x.Cars));

它会删除 dbPerson.Cars 中的所有实体并将 _person.Cars 添加到 dbPerson.Cars 并保存。这意味着数据库中我的 Cars 表中的所有记录都将被删除,并插入 _person.Cars 中的记录。我注意到这种情况正在发生,因为现在子实体没有 Id 属性。我必须手动设置它们。

  foreach(var car in _person.Cars)
        car.PersonId = _person.Id

现在如果你打电话

   Context.UpdateGraph(_person, m => m.OwnedCollection(x => x.Cars));  

这将从持久对象中缺少的瞬态对象添加集合中的实体,并更新持久对象中匹配的对象,并从持久对象中删除其余实体。

     var dbCars = conext.Where(x => x.Personid == _person.Id).Select(x).ToList();

说 dbCars.Count 是 8,_person.Cars.Count 是 3。(一辆新车和两辆旧车更新了值) 一旦你运行。

    Context.UpdateGraph(_person, m => m.OwnedCollection(x => x.Cars));

dbCars 中匹配的 _person.Cars 中的 2 辆旧车将被更新。 将添加 1 辆来自 _person.Cars 的新车在 dbCars 中不匹配。

现在 dbCars 的计数必须为 9,因为我们添加了一辆新车。现在检查计数。

  var dbCarCount = conext.Where(x => x.Personid == _person.Id).Select(x).ToList().Count();

dbCarCount 将是 3。dbCars 中剩下的 6 辆车正在被移除。

我希望我错了,因为我喜欢使用您的解决方案。我在这方面的工作停滞不前。如果我遗漏了什么或者您需要更多信息,请告诉我。我知道我的文章令人困惑,因为我试图将我所有的测试经验都放在 GraphDiff 上。希望您解决这个问题。

【问题讨论】:

  • "现在 dbCars 的数量必须是 9" - 为什么?如果断开的图不再包含其他 6 辆车,发生了什么?确定被删了吗?为什么他们还不在那里?
  • "现在 dbCars 的计数必须是 9" - 为什么?[Mady:最初有 8 个我添加了一辆新车并更新了 2 个现有汽车的详细信息,因此计数应该是 9。]图不再包含其他 6 辆车发生了什么?他们肯定被删除了吗?[Mady:是的,他们被删除了。]为什么他们不在那里?[Mady:因为 GraphDiff 仅适用于我发现的断开连接的父实体和连接的子实体。我可能错了,使用 graphdiff 的人会纠正我。我在下一条评论中的例子]
  • 示例:我有一个包含书籍集合的作者实体,我从各个客户端获取此实体以保存到数据库中。许多客户很有可能发送具有相同/不同书籍集合的作者实体.如果存在,我必须更新书籍,如果不存在,我必须添加。我们不会从图表中删除。

标签: entity-framework-6 graphdiff


【解决方案1】:

如果您有一个断开连接的图表,并且您想将其合并到数据库中,那么它应该做 3 件事:

  1. 插入新实体
  2. 更新现有实体
  3. 删除不在图表中的实体

您似乎对最后一部分有疑问。

如果首先没有从数据库中检索到图形,那么您没有按预期使用 GraphDiff。您必须手动添加和更新。

【讨论】:

  • 绝对正确。如果我在代码中注释删除逻辑,我仍然可以在这个特定场景中使用 GraphDiff。如果我不得不使用删除功能,我不会使用 GraphDiff。
  • 是的。或者你可以添加一个标志/枚举来切换模式
  • 是的。我想知道这是否是 GraphDiff/EntityFramework 在未来版本中解决的有效案例。对我来说,这是一个有效的案例,因为大多数从各种来源收集数据的数据聚合项目都会遇到这种情况。感谢您分享想法:)
  • 如果您想投票并跟踪更新以更好地支持在 EF 中使用断开连接的实体,请转到此处:entityframework.codeplex.com/workitem/864
  • 我是一周前做的。谢谢!
【解决方案2】:

我为此找到了两个工具:

  1. Trackable-Entities
    • 支持缓存和存储断开连接的图形的轻量级客户端-服务器工具。
    • 支持 PCL、Xamarin 和其他平台
    • MIT 许可证
  2. Breeze#
    • 成熟的客户端-服务器工具,支持缓存和存储断开连接的图表。
    • UWP 不支持
    • 维护成本极低
    • MIT 许可

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    相关资源
    最近更新 更多