【问题标题】:Javascript JSON serialize only first levelJavascript JSON 仅序列化第一级
【发布时间】:2014-08-24 23:54:53
【问题描述】:

我正在客户端使用 AngularJS 构建应用程序,后端使用 ASP.NET WebAPI/Entity Framework。

我需要确保完整的事务被存储或回滚,而不是依赖纯粹的 RESTful 服务。因此,我编写了一个 JavaScript UnitOfWork 实现,它跟踪我加载的每个对象,并按类型分别存储它们。

我在持久化它们时遇到了问题。

假设我通过 Web API 加载了以下对象:

{
    FirstName: "Bob",
    LastName: "Jensen",
    Email: "test@example.com",
    Country: { ID: 61, Name = "Zimbabwe"},
    CountryID: 61,
    Animals: [
        { Name: "Mittens", ID: 2},
        { Name: "Rex", ID: 1}
    ]
}

现在,假设我更改了 Bobs LastName 并想保存它。我将我的 UoW 发送到服务器,然后在 EF 上下文中,我对我编辑的对象执行以下操作(在此之前没有代码接触 obj):

databaseContext.Entry(obj).State = EntityState.Modified;

这给了我这样的错误:

附加类型为“MyApp.Model.Country”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。

我的第一个想法是在将不需要的属性发送回服务器之前将其删除 - 所以在我上面的 JSON 中,我应该发回类似的结果,但没有“国家”和“动物”属性。我仍然想保留 CountryID。

  1. 如果不明确指定要删除的属性,这是否可行?
  2. 由于我面临这个问题,我的方法在概念上是否存在问题?我应该改为处理这个服务器端吗?

【问题讨论】:

  • 我敢打赌你的上下文的生命周期太长了。
  • 嗯.. 这实际上是一个我什至没有考虑过的有趣点。它存储在我的 ASP.NET 控制器上的一个私有字段中。我必须承认,我没有考虑过控制器被实例化的频率,只是假设它是每个请求一次。我认为我错了,明天会调查这个。谢谢!不过,我不希望为要发送的每个 UnitOfWork 序列化整个对象图。
  • @GertArnold:我检查过了,没有——我的控制器在每个请求上都会被实例化,所以我的内容只能用于一个查询/操作。
  • 是的,这是 MVC 中的默认行为。但不知何故,这个实体在你显示的行之前被附加了。你能显示一些周围的代码吗?
  • 你是如何获取 obj 的?我在某处看到有一些方法可以从数据库中获取它,这些方法已经将其标记为已修改,因此您只需要更新数据而不触及状态

标签: c# javascript json angularjs entity-framework


【解决方案1】:

通过删除我的 JavaScript 对象上的集合和对象引用来使其正常工作:

var clone = {};
for (prop in obj) {
    if (typeof obj[prop] == "string" || typeof obj[prop] == "number" || typeof obj[prop] == "boolean") {
        clone[prop] = obj[prop];
    }
}

现在 EF 很高兴,我通过不发送整个图表节省了极少的带宽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 2021-07-05
    相关资源
    最近更新 更多