简体   繁体   English

为什么实体框架在应该更新时插入?

[英]Why is the Entity Framework inserting when it should update?

I use the following RIA Services call to register and return a Project entity.我使用以下 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;
}

As you can see, it calls a stored procedure that returns a project ID.如您所见,它调用了一个返回项目 ID 的存储过程。 It uses this ID to look up the Project entity itself and return it.它使用此 ID 来查找Project实体本身并返回它。 When the Project entity is returned to the client it is detached.Project实体返回给客户端时,它会被分离。 I attach it to the DomainContext and modify it.我将它附加到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";
} 

At this point it has an entity state of Modified .此时它有一个实体 state 的Modified When I submit changes it gives me an exception regarding a UNIQUE KEY violation as if it is trying to insert it rather than update it.当我提交更改时,它会给我一个关于 UNIQUE KEY 违规的异常,就好像它试图插入它而不是更新它一样。

// At Client
_context.SubmitChanges(OnProjectSaved, a_callback);

I'm using the same DomainContext instance for all operations.我对所有操作使用相同的DomainContext实例。 Why should this not work?为什么这不起作用?
What's going wrong?怎么了? This is rather frustrating.这是相当令人沮丧的。

Edits:编辑:

I tried this (as suggested by Jeff):我试过这个(正如杰夫所建议的那样):

[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();
}

It did absolutely nothing.它完全没有做任何事情。 It didn't save the project.它没有保存项目。

What happens if you add a SaveProject method on the server side and send the object back to the server for saving?如果您在服务器端添加 SaveProject 方法并将 object 发送回服务器进行保存,会发生什么情况?

I've not done EF with RIA Services, but I've always sent my objects back to the server for saving.我没有使用 RIA 服务完成 EF,但我总是将我的对象发送回服务器进行保存。 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.我假设 SubmitChanges 调用您正在为您正确连接所有内容以将其发送回服务器,但也许它做错了什么并且手动处理它会修复它。

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.我目前没有源代码,但我看到它建议您为 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.我今天遇到了类似的问题,这是因为我使用了一个服务级别的上下文,它记住了我不想要的以前的值,我改为为每个服务调用创建一个新的上下文,并且行为变成了我的预期。

public void SaveResponses(ICollection<Responses> items, Action<SubmitOperation> callback)
        {
            try
            {
                SurveysDomainContext _context = new SurveysDomainContext();
                foreach (Responses item in items)
                {
                    _context.Responses.Add(item);
                }

                _context.SubmitChanges(callback, null);
            }
            catch (Exception)
            {

                throw;
            }

        }

As for the notion that one can't use a singleton global DomainContext, this is actually debatable.至于不能使用 singleton 全局域上下文的概念,这实际上是有争议的。 In my project I use a singleton DomainContext with no issues.在我的项目中,我使用 singleton DomainContext 没有问题。 In other projects, we have created a new DomainContext for different modules in the app where the entities are reused.在其他项目中,我们为应用程序中的不同模块创建了一个新的 DomainContext 实体被重用。 There are definitely pros and cons.肯定有好处也有坏处。 See: Strategies for Handling Your DomainContext (external blog)请参阅: 处理 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.似乎问题在于,当您将项目附加到 DomainContext 时,它会检查 _context.Projects 实体集并且没有找到具有该主键的实体,然后假定新附加的实体尚不存在服务器端并且提交更改应该插入它。 A possible workaround might be to explicitly load the newly created Project into the DomainContext.一种可能的解决方法可能是将新创建的项目显式加载到 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.它将确保它在实体上设置正确的 state - 也就是说,该项目已经存在于服务器上并且它是一个更新实例,而不是一个插入实例。

So maybe something like:所以也许是这样的:

//after your Project has already been created serverside with the invoke
_context.Load(_context.SomeQueryThatLoadsYourNewlyCreatedProject(), LoadBehavior.RefreshCurrent, (LoadOperation lo) => {
    Project project = lo.Entities.FirstOrDefault(); //is attached and has correct state
    if (project != null)
    {
        project.AuthenticationType = "strong";
        project.OwnerID = customer.ID;
        project.Do(pi => _activeProject.ProjectItems.Add(pi));
        project.Status = "calculationrequired";
        _context.SubmitChanges(); //hopefully will trigger an update, rather than an insert
    } 
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过服务在数据库中插入实体时出现问题 - Problem when inserting an entity in the database through a service 托管时,实体框架返回null - Entity framework returns null when hosted 仅使用实体框架和RIA服务更新已修改的列 - Update modified columns only, with Entity Framework and RIA services 为什么Silverlight 4将WCF RIA服务用于Entity Framework? - why Silverlight 4 uses WCF RIA service for Entity Framework? 为什么Entity Framework不为nvarchar(MAX)字段返回修剪后的字符串? - Why does Entity Framework not return a trimmed string for a nvarchar(MAX) field? 远程调用实体框架中的存储过程时,服务器没有响应 - No response from server when calling stored procedure in entity framework remotely 从框架控件继承时,应该调用基本构造函数吗? - When inheriting from a framework control, should I call the base constructor? 使用实体框架动态设置连接字符串时的Silverlight安全问题 - Silverlight Security Concern when Dynamically Setting Connection String with Entity Framework Silverlight&RIA&POCO:插入两个新的子实体时,SubmitOperationFailed。 存在具有相同ID的实体 - Silverlight & RIA & POCO: SubmitOperationFailed when INSERTING two new child entities. An entity with the same ID exists 实体框架字段枚举 - Entity Framework Field Enumeration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM