为什么实体框架在应该更新的时候却插入了?
我使用以下 RIA 服务调用来注册并返回 Project
实体。
// On Server; inside RIA Domain Service
[Invoke]
public Project CreateNewProject(String a_strKioskNumber)
{
Decimal dProjectID = ObjectContext.RegisterProjectNumber(a_strKioskNumber)
.FirstOrDefault() ?? -1m;
// Tried this but it returned zero (0)
//int nChanged = ObjectContext.SaveChanges();
var project = (from qProject in ObjectContext.Projects.Include("ProjectItems")
where qProject.ID == dProjectID
select qProject)
.FirstOrDefault();
if (project == null)
return null;
return project;
}
正如您所看到的,它调用一个返回项目 ID 的存储过程。它使用此 ID 查找 Project
实体本身并返回它。当 Project
实体返回给客户端时,它被分离。我将其附加到 DomainContext
并修改它。
// At Client
_activeProject = a_invokeOperation.Value; // <-- Detached
_context.Projects.Attach(_activeProject); // <-- Unmodified
if (_activeProject != null)
{
_activeProject.AuthenticationType = "strong"; // <-- Modified
_activeProject.OwnerID = customer.ID;
_projectItems.Do(pi => _activeProject.ProjectItems.Add(pi));
_activeProject.Status = "calculationrequired";
}
此时它的实体状态为Modified
。当我提交更改时,它给了我一个有关 UNIQUE KEY 违规的异常,就好像它试图插入它而不是更新它一样。
// At Client
_context.SubmitChanges(OnProjectSaved, a_callback);
我对所有操作使用相同的 DomainContext
实例。为什么这不起作用?
出了什么问题?这是相当令人沮丧的。
编辑:
我尝试了这个(按照杰夫的建议):
[Invoke]
public void SaveProject(Project a_project)
{
var project = (from qProject in ObjectContext.Projects
where qProject.ID == a_project.ID
select qProject)
.FirstOrDefault();
project.SubmitDate = a_project.SubmitDate;
project.PurchaseDate = a_project.PurchaseDate;
project.MachineDate = a_project.MachineDate;
project.Status = a_project.Status;
project.AuthenticationType = a_project.AuthenticationType;
project.OwnerID = a_project.OwnerID;
project.ProjectName = a_project.ProjectName;
project.OwnerEmail = a_project.OwnerEmail;
project.PricePerPart = a_project.PricePerPart;
project.SheetQuantity = a_project.SheetQuantity;
project.EdgeLength = a_project.EdgeLength;
project.Price = a_project.Price;
project.ShipToStoreID = a_project.ShipToStoreID;
project.MachiningTime = a_project.MachiningTime;
int nChangedItems = ObjectContext.SaveChanges();
}
它绝对没有任何作用。它没有保存该项目。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果在服务器端添加一个 SaveProject 方法并将对象发送回服务器进行保存,会发生什么情况?
我没有使用 RIA 服务完成 EF,但我总是将对象发送回服务器进行保存。我假设 SubmitChanges 调用您正在为您正确连接所有内容,以便将其发送回服务器,但也许它做错了什么,手动处理它可以修复它。
What happens if you add a SaveProject method on the server side and send the object back to the server for saving?
I've not done EF with RIA Services, but I've always sent my objects back to the server for saving. I'm assuming that SubmitChanges call you are making wires up everything properly for you for sending it back to the server, but perhaps it is doing something wrong and handling it manually will fix it.
我目前没有源代码,但我看到它建议您为 Silverlight 中的每个操作使用新的上下文。我今天遇到了类似的问题,这是因为我使用的服务级别上下文记住了我不想要的以前的值,我改为为每个服务调用创建一个新的上下文,并且行为变成了我的预期。
I dont have the source at the moment but I have seen it recommended that you use a new context for each operation in Silverlight. I ran into a similar problem today and it was because I was using a Service level context that was remembering previous values that I didnt want, I changed to creating a new context for each service call and the behavior became what I expected.
至于不能使用单例全局 DomainContext 的概念,这实际上是有争议的。在我的项目中,我使用单例 DomainContext 没有任何问题。在其他项目中,我们为应用程序中的不同模块创建了一个新的 DomainContext,其中实体被重用。肯定有优点和缺点。看:
处理 DomainContext 的策略(外部博客)
As for the notion that one can't use a singleton global DomainContext, this is actually debatable. In my project I use a singleton DomainContext with no issues. In other projects, we have created a new DomainContext for different modules in the app where the entities are reused. There are definitely pros and cons. See:
Strategies for Handling Your DomainContext (external blog)
问题似乎在于,当您将项目附加到 DomainContext 时,它会检查 _context.Projects 实体集,但没有找到具有该主键的实体,然后假设新附加的实体在服务器端尚不存在,并且提交更改应该插入它。一种可能的解决方法是将新创建的项目显式加载到 DomainContext 中。它将确保它在实体上设置正确的状态,即该项目已存在于服务器上并且它是更新实例,而不是插入实例。
所以也许是这样的:
It seems that the problem is that when you attach your project to the DomainContext it checks the _context.Projects entityset and isn't finding an entity with that primary key, and then assumes that the newly attached entity doesn't exist serverside yet and that submitting changes should insert it. A possible workaround might be to explicitly load the newly created Project into the DomainContext. It would ensure that it sets the correct state on the entity--that is, that the project already exists on the server and that that it's an update instance, rather than an insert instance.
So maybe something like: