2016-01-06 95 views
1

我正在使用Silverlight 4和DevForce 6.1.11.0为什么EntityAspect.RemoveFromManager不能完全删除?

我有一些实现EntityAspect的POCO类。

我使用WebClient从不同的设备获取这些实体。这些设备没有DevForce服务器。 将实体添加到实体管理器时,首先使用entityManager.FindEntities<PocoSomeEntity>(EntityState.AllButDetached)检查具有密钥的实体不存在于高速缓存中。然后,我创建实体并添加这样的:

entityManager.AddEntity(entity); 
entity.EntityAspect.AcceptChanges(); 

我可以添加,修改和删除实体和将其保存到设备 - 到目前为止,没有任何问题。

最近我实现了一个“清除缓存”使用entity.EntityAspect.RemoveFromManager(true); 这似乎工作期望,如果我删除一个实体(EntityAspect.Delete()),然后从管理员删除它,然后尝试加载回。当重装调用EntityAspect.AcceptChanges()实体,它会抛出一个“已经存在”异常。

我该如何解决此问题?

编辑

这是AddEntity()抛出异常。

这里是堆栈跟踪:

​​

我的实体具有复合键。 我搜索缓存,但我什么也没找到:

// returns nothing 
var instancesInManager = entityManager.FindEntities<PocoSomeEntity>(EntityState.AllButDetached).Where(i => i.p_key1 == 41 && i.p_key2 == 5448); 
// returns nothing 
var detachedInstancesInManager = entityManager.FindEntities<PocoSomeEntity>(EntityState.Detached).Where(i => i.p_key1 == 41 && i.p_key2 == 5448); 

我也搜索了键,但没有发现任何能解释这种现象:

// returns instances, but none have keys with zeros or the key that I am looking for. 
var instancesInManager = entityManager.FindEntities<PocoSomeEntity>(EntityState.AllButDetached); 
// returns no results 
var detachedInstancesInManager = entityManager.FindEntities<PocoSomeEntity>(EntityState.Detached); 

EDIT2

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
using System.Runtime.Serialization; 
using IdeaBlade.Core.DomainServices; 
using IdeaBlade.EntityModel; 
using IbVal = IdeaBlade.Validation; 

namespace ServerModel 
{ 
    [DataContract(IsReference = true)] 
    public class PocoSomeEntity : IKnownType, IHasPocoEntityAspect, INotifyPropertyChanged 
    { 
     public PocoSomeEntity() { } 

     private int m_key1; 

     [Key] 
     public int p_key1 
     { 
      get { return m_key1; } 
      set { m_key1 = value; OnPropertyChanged("p_key1"); } 
     } 

     private int m_key2; 
     [Key] 
     public int p_key2 
     { 
      get { return m_key2; } 
      set { m_key2 = value; OnPropertyChanged("p_key2"); } 
     } 

... 

     #region IHasPocoEntityAspect Members 

     [Display(AutoGenerateField = false)] 
     [IgnoreDataMember] 
     public IdeaBlade.EntityModel.EntityAspect EntityAspect 
     { 
      get; 
      set; 
     } 

     #endregion 

     #region INotifyPropertyChanged Members 

     /// <summary> 
     /// This interface implementation is needed if you want EntityManager to automatically listen 
     /// to any property change. 
     /// </summary> 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(String propertyName) 
     { 
      var handler = PropertyChanged; 
      if (handler != null) 
      { 
       var args = new PropertyChangedEventArgs(propertyName); 
       handler(this, args); 
      } 
     } 

     #endregion 
    } 
} 
+0

我没有在测试中看到了这个问题。如果密钥已经存在于EM缓存中,则在执行AddEntity()时将抛出异常。在添加之前检查EntityKey的值 - 如果它是类似于0或可能有助于缩小问题范围的tempid,或者提供更多信息来诊断它。 –

+0

我在帖子中增加了更多细节。在进行AddEntity之前,实体没有EntityAspect,我无法检查EntityKey。在AddEntity之后,它抛出异常。在此之后,EntityKey是正确的,但实体已分离。 –

+0

错误消息中显示的实体键是否是正确的键?我仍然想知道它是否可能被设置为零或由临时ID生成器分配负ID。如果看起来和预期的一样,你也可以用正确的键值构造一个EntityKey,然后调用em.FindEntity(entityKey)来查看是否在缓存中找到匹配项。 –

回答

1

看起来您已经发现了SL版本DevForce中的一个错误。问题在于DF如何处理实体上的EntityKey,因为它没有为某些实体状态和实体版本设置基础属性值。在这里,尽管执行了Add和AcceptChanges,但DF仍然没有为EntityKey设置后台字段,这会导致稍后的奇怪行为。

有几个解决方法可能比您实施的查找逻辑更容易。

  • 第一个是对这些POCO实体使用Attach而不是Add/AcceptChanges。代码路径DF在实体被连接时跟随,因为“不变”确保EntityKey设置正确。

    manager.AttachEntity(entity); 
    
  • 如果用例要求的实体处于“增加”状态时,另一个解决方法是做一个的AcceptChanges,这确保了的EntityKey支持字段被正确地设置之后调用的EntityKey吸气剂。例如,

    manager.AddEntity(entity); 
    entity.EntityAspect.AcceptChanges(); 
    var ek = entity.EntityAspect.EntityKey; 
    
+0

你救了我的一天!我去了AttachEntity解决方法,它似乎完美。 –

0

一种解决方法要再次检查FindEntity()。如果存在,则重新填充其属性并将其添加回管理器。

// Check if entity already exists in manager 
var instancesInManager = entityManager.FindEntities<PocoSomeEntity>(EntityState.AllButDetached).Where(i => i.p_key1==key1 && i.p_key2==key2); 
var entity = instancesInManager.FirstOrDefault(); 
if (entity == null) 
{ 
     PocoSomeEntity i; 

     // Double check if entity really exists in manager :) 
     var doubleCheck = entityManager.FindEntity(new EntityKey(typeof(PocoSomeEntity), key1, key2)); 
     if (doubleCheck != null) 
     { 
       i = (doubleCheck as PocoSomeEntity); 
     } 
     else 
       // If it does not exists, then we can create it 
       i = new PocoSomeEntity(); 

     i.p_key1 = key1; 
     i.p_key2 = key2; 

     // populate or re-populate entity properties 
     ... 

     entityManager.AddEntity(i); 
     i.EntityAspect.AcceptChanges(); 
} 

编辑

如果我删除了相同类型的两个或多个实体的解决方法不起作用。