问题标签 [graphdiff]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1573 浏览

entity-framework - 表达式树中的异常

这是我的模型:

现在我有一个控制器动作,它接受一个表单,该表单由整个数据作为一个Business实体组成,其所有属性和集合都设置得很好。

现在我必须递归遍历所有属性和集合,并与数据库图进行比较;如果它们不存在,则添加它们,如果它们确实再次遍历所有属性并执行相同的更深层次,直到没有留下任何导航属性。由于我有比上一个示例中提到的更多的属性和后代,所以它只是在里面手动遍历它们。

多亏了这个答案,我发现 GraphDiff 为这种情况提供了一个绝妙的解决方案。

这是我正在调用的更新查询:

它抛出这个异常:

System.InvalidCastException:无法将“System.Linq.Expressions.MethodCallExpressionN”类型的对象转换为“System.Linq.Expressions.MemberExpression”类型。

我尝试调试源代码,但我不是表达式树的专家,当内部Include调用(包括对象图以加载存储对象)尝试附加时会出现问题WorkingPeriods,看起来它还没有准备好接受那个深度级别递归。我有点搞砸了,但我相信在表达式树方面具有广泛知识的人将能够轻松解决这个问题。任何建议将不胜感激。

这是包含路径表达式应该生成的内容:

这是错误的堆栈跟踪。

本质上,抛出异常是因为递归调用将内部包含作为方法调用返回,而不对其进行处理并返回它打算公开的集合属性。

0 投票
2 回答
3340 浏览

entity-framework-6 - 具有断开子实体的断开复杂图

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

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

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

在这一点上,我们不确定我们收到的对象是否必须添加或更新。子实体(汽车)上的 PersonId 也将为 0。现在,如果我们调用。

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

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

现在如果你打电话

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

说 dbCars.Count 是 8 并且 _person.Cars.Count 是 3。(一辆新车和两辆更新值的旧车)一旦你跑了。

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

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

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

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

0 投票
1 回答
3196 浏览

c# - 如何使用 GraphDiff 更新表达式树

我正在使用的对象图基本上是:

通过选择现有技术、技能类别、技能能力的组合,可以向用户添加新技能。我一直在尝试(但失败了!)使用 GraphDiff 来防止 EF 尝试添加重复的 Technology、SkillCategory、SkillCompetency 记录。这似乎使用 GraphDiff 实现起来应该很简单,但是对于 EF 夫妇来说是一个相对较新的人,只是发现 GraphDiff 我正在苦苦挣扎。

有任何想法吗?

0 投票
0 回答
154 浏览

graphdiff - GraphDiff 是否在数据库优先场景中工作?

我在具有现有 SQL Server 数据库的应用程序中使用实体框架。假设我使用 POCO 实体生成器,GraphDiff 可以在数据库优先场景中使用吗?

0 投票
1 回答
2609 浏览

c# - 使用 GraphDiff 更新多对多关联

我有以下数据模型:

数据模型

我的业务逻辑适用于分离的实体,因此我使用 GraphDiff 来执行更新。我在更新 PerfModes/CalcPoints 关联时遇到问题。从概念上讲,Block 拥有 CalcPoints 和 PerfModes,但 CalcPoints 可以与任意数量的 PerfModes 相关联。

我正在尝试在块级别进行更新。我想出的代码不会引发任何错误(而其他尝试会),但它也不会更新 PerfModes/CalcPoints 关联。

我可能没有完全掌握 EF 图和 GraphDiff。如何确保正确更新多对多 PerfModes/CalcPoints 关联?

编辑

在查看了andyp的回答后,我从GitHub上下载了最新版本的GraphDiff,并尝试了以下映射:

这会正确更新我的 PerfModes/CalcPoints 关联。我切换回原来的映射,但仍然看到关联未更新的问题,因此尝试一次更新整个模型似乎存在问题。我可以进行多个 UpdateGraph 调用,但是将它们分解的最佳方法是什么?

这是带有相关代码和失败的单元测试的要点。

我继承了 EF 生成的容器类来创建我自己的上下文,并禁用了代理创建。这会导致 GraphDiff 出现问题吗?

0 投票
1 回答
147 浏览

c# - 将表达式转换为另一个表达式

我有以下表达

Expression<Func<T, object>> expr1;

有什么办法可以将它投射到

Expression<Func<IUpdateConfiguration<T>, object>>?

[更新]

Expression<Func<IUpdateConfiguration<T>, object>>或者从现有的创建一个新的Expression<Func<T, object>>

0 投票
1 回答
782 浏览

c# - 在断开连接的环境(EF)中使用 Db 生成的 Id 更新实体图 Id

我正在EF6 code first一个WinForm项目中工作。我使用以下方法从中读取实体Db,更新它们,然后将它们保存回Db

  1. Linq to entities使用(阅读DbContext处置后)阅读实体图
  2. 向最终用户显示读取Entity的图表。
  3. 最终用户可以将此更改应用于Entity图形:
    • 更新根实体
    • 添加一些子实体
    • 编辑一些子实体
    • 删除一些子实体
  4. 用户调用一个方法来将他的更改持久化到Db
  5. 创建一个新DbContext实例。
  6. 重新加载相同Entity的图表Db
  7. 使用将所有属性的值从用户实体映射到重新加载的实体AutoMapper
  8. 将 6 步的结果实体附加到我的DbContextusingGraphDiff
  9. 调用DbContext.SaveChanges();以保持更改Db 在此处输入图像描述

    /li>


它工作正常,

在第二张图中,用户添加了 Child13 和 Child22,当我调用uow.SaveChanges()它们时,它们将保存到Db并且它们Id的 s 将被分配。但是在对象中Child13.Id,我可以手动更新s 但我正在寻找通用方法来使用生成的 s更新这些值。Child22.Identity0IdIdDbId

0 投票
2 回答
225 浏览

web-services - 如何执行面向服务的父子事务?

例子:

SalesOrder 由 SalesOrderHeader 和一个或多个 SalesOrderItems 组成。在编辑现有的 SalesOrder 时,可以修改 SalesOrderHeader 并且可以添加、修改和删除 SalesOrderItems。所有更改必须保存在单个事务中。多个用户可以以乐观并发同时编辑 SalesOrder。

我相信在单个事务中完成保存的要求鼓励我们在单个服务调用中同时传达 SaleOrderHeader 和 SalesOrderItems。将子数据与其父数据打包的含义是,需要对子数据是否被添加、修改或删除有所了解。

子实体的更改跟踪可以发生在服务器或客户端上。

服务器上的更改跟踪

这个策略的想法是,客户端可以根据自己的意愿修改 SalesOrder,而无需跟踪添加、修改或删除了哪些 SalesOrderItem。SalesOrderItems 的状态将在调用保存服务时在服务器上确定。

服务器应该在服务调用之间保持无状态。这意味着服务器无法保留任何有关 SalesOrder 在检索和最终保存之间状态的信息。如果服务器通过将修改后的对象图与数据库对象图进行比较来确定其实体的状态,则剩下的唯一选择。

使用 nHibernate,有一个合并功能来完成此操作。使用实体框架,最高投票的功能请求是添加此功能。还有一个用于 EF 的开源实现,称为GraphDiff

这在理论上听起来很棒,因为它使服务非常易于设计和使用。但是,我发现此策略存在两个主要问题。首先是性能。每次保存时必须将整个对象图发回。无论是否修改了 SalesOrderItem,都必须将其发回,否则服务器将假定它已被删除。第二个问题更为关键,它与并发有关。如果用户 1 将 SalesOrderItem 添加到 SalesOrder 并且用户 2 对相同的 SalesOrder 进行了更改,则当用户 2 保存时,服务器将假定用户 1 添加的 SalesOrderItem 应该被删除,因为它不包含在用户 2 的对象图中。我看不到在任何服务器端更改跟踪的实现中都可以防止这种情况发生。

客户端上的更改跟踪

另一种方法是让客户端跟踪其实体的更改并在调用保存服务时传达该状态。一个好处是客户端不需要发送其未更改的子实体。这有助于提高性能。缺点是所有实体都需要一个名为“ObjectState”的附加属性来跟踪它是否被添加、修改或删除。这使得服务器上的实体模型非常混乱,并且充满了与业务领域无关的关注点。这也让服务的不同消费者有责任维持这种状态。另一个问题是处理已删除的实体变得困难。SalesOrderHeader 是否应该维护已删除的 SalesOrderItems 列表?还是应该为 SalesOrderItems 分配一个必须由客户端 UI 过滤掉的已删除状态?

我知道微风javascript 库有自己的客户端实体跟踪实现,但我担心它的实现需要客户端和服务器端组件。服务层不应该隔离我们在任何一方使用的技术吗?如果非 JavaScript 客户想要使用我的服务怎么办?

问题

我认为这是一个常见的场景,应该由大多数服务实现来解决。我有没有做出任何不正确的假设,或者我做了什么不正常的事情或普通的事情?你实施了什么策略?有没有合理的替代方案?

0 投票
0 回答
247 浏览

c# - 如何防止 GraphDiff 删除对象图中丢失的子项?

我目前正在开展一个项目,该项目要求我们能够在某个时间点提取对象和关联子项的确切状态。为此,我们提出了一个与此类似的模型:

假设你有一个对象:

这将按预期使用 GraphDiff 保存。然后稍后,我们加载父 1v1,并对其进行更改。版本将达到 2,子对象版本将达到 2。所以现在这个对象:

也会像我们想要的那样保存。为这些对象中的每一个插入一条新记录,并保留旧版本。但是,如果我们只更改子 1 对象,那么我们从上面的模型转到:

并使用GraphDiff保存,发现Child 1v2不再在图中,将其从数据库中删除。我看到的唯一方法是必须有 2 个 get 方法。一个加载实际可用的内容,最大版本的父级和子级,另一个加载整个图表,包括每个历史对象。

我不想那样做。这篇宣布新 GraphDiff 功能的博客文章似乎表明可能有一些审计功能可用,但我找不到任何关于如何使用它的文档。

有没有办法在仅添加/更新模式下使用 GraphDiff?

0 投票
0 回答
1405 浏览

c# - 使用一对一关系更新图

我有一个类 Ricevuta,其中包含 VoceRicevuta 的集合:

VoceRicevuta 包含对不同类的可选引用,让我们只考虑对 Prestazione 类的引用:

好的,现在的问题如下:我创建了一个 Prestazione 实例(我们称之为 PreInst)并将其保存到数据库中。我将 PreInst 从该 DbContext 实例中分离出来。然后,我将 PreInst 传递给另一个表单(另一个 DbContext - 我必须这样做),创建一个 Ricevuta、一个 VoceRicevuta(添加到刚刚创建的 Ricevuta 中)并将 PreInst 分配给 VoceRicevuta Prestazione 属性。我还对 PreInst 做了一些更改。现在我想将新的 Ricevuta、新的 VoceRicevuta、它与 PreInst 的关系以及对 PreInst 的更改保存到数据库中。我运行以下命令:

但我得到错误:

“违反主键约束‘PK_dbo.Prestazioni’。无法在对象‘dbo.Prestazioni’中插入重复键。重复键值:(12115)”

我不明白为什么!如果图形的任何部分已经存在于 Db 中并且行为结果,Graph diff 目的不是检查吗?

在运行上面的代码并保存之前,我尝试将 PreInst 附加到 DbContext。现在抛出的错误是:

有什么提示吗?