我有一个 Web 服务,它返回一些数据,然后将其转换为服务器上的新实体,然后传递给客户端,用户可以在其中编辑它们。如果他选择SaveChanges
,实体应该被提交到服务器并插入到数据库中。我有两个问题:
- 当实体返回给客户端时,Breeze 将它们标记为
EntityState.New
- Breeze 预计,未更改的实体具有主键集。因为返回的新实体都没有键集(Int32 类型的键值等于 0),Breeze 认为服务器返回了同一实体的多个实例
为了演示该问题,更改ToDosController.ToDos
AngularJS 示例中的方法以匹配以下内容:
[HttpGet]
public IEnumerable<TodoItem> Todos()
{
return new TodoItem[]
{
// Keys are not set because (equals to 0) these are new entities
new TodoItem() { Description="First item"},
new TodoItem() { Description="Second item"},
};
}
当您运行示例时,HTML 页面将显示两行,两行都有描述“第二项”。如果我在服务器上显式设置这些项目的 ID(我不想这样做,因为密钥是由数据库生成的),则问题不会出现。
问题:如何正确地从服务器返回实体,以便在调用EntityState.New
时将它们标记为并保存到数据库中(使用生成的密钥)SaveChanges
。
我希望MergeStrategy
客户端上的一些或服务器上的一些额外数据/属性来实现这一点,但找不到。
更新:
澄清:
当用户选择并编辑源自其他来源的实体之一时,我尝试支持这样一种场景,该实体稍后应添加到我的数据库中。
详细说明:
客户端使用搜索条件作为方法参数调用服务器。服务器方法返回
IEnumerable<Customer>
- 它不返回IQueriable<Customer>
服务器查询后端 Web 服务(CRM 系统)并将后端 Web 服务的结果转换为
Customer
实体。结果返回给客户端。后端 Web 服务对客户端不可用。客户端向用户显示结果
用户选择实体之一并编辑其属性(例如更改客户名称或地址)
选定的客户被添加到客户端的实体管理器中。它应该在
EntityState.Added
em.SaveChanges
被调用,它将Add
ed实体提交给服务器服务器将新客户插入数据库,数据库生成新的主键,返回给客户端,其中 EM 更新实体键并将实体状态设置为
EntityState.Unchanged
也许我需要分离的实体,正确的问题是:“如何在不将实体添加到实体管理器的情况下将实体返回给客户端?” (它们将在上面的步骤 5 中添加)。
PS:一种解决方案是使用自定义的非实体数据类型(例如 CustomerFromCRM)作为我的服务器方法的结果。然后我会将它们转换为客户端的实体 Customer。但我想避免创建额外的类。
UPDATE2:我在这里发现了一个类似的问题(没有接受的答案):是否有一种简单的方法可以将缓存中的实体标记为“已添加”?