为什么EntityAspect.RemoveFromManager没有完全删除?

时间:2016-01-06 09:07:20

标签: silverlight-4.0 devforce

我正在使用Silverlight 4和DevForce 6.1.11.0

我有一些实现EntityAspect的POCO类。

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

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

我可以添加,修改和删除实体并将它们保存回设备 - 到目前为止没问题。

最近我使用entity.EntityAspect.RemoveFromManager(true);实现了“清除缓存” 如果我删除一个实体(EntityAspect.Delete()),然后将其从管理器中删除,然后尝试将其重新加载,这似乎有用。当在重新加载的实体上调用EntityAspect.AcceptChanges()时,它会抛出“已经存在“例外。

如何解决此问题?

修改

抛出异常的是AddEntity()

这是堆栈跟踪:

   at IdeaBlade.EntityModel.EntityGroup.AddToKeyMap(EntityAspect aspect)
   at IdeaBlade.EntityModel.EntityGroup.AddEntityCore(EntityAspect aspect)
   at IdeaBlade.EntityModel.EntityGroup.AddAttachedEntity(EntityAspect aspect, EntityState entityState)
   at IdeaBlade.EntityModel.EntityManager.AttachEntityAspect(EntityAspect aspect, EntityState entityState)
   at IdeaBlade.EntityModel.EntityManager.AttachEntity(Object entity, EntityState entityState)
   at IdeaBlade.EntityModel.EntityManager.AddEntity(Object entity)
   at ...

我的实体有一个复合键。 我搜索了缓存,但我一无所获:

// 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
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

  • 第一种是对这些POCO实体使用Attach而不是Add / AcceptChanges。当实体附加为&#34;未更改&#34;时,代码路径DF跟随。确保正确设置EntityKey。

    manager.AttachEntity(entity);
    
  • 如果用例要求实体位于&#34;添加&#34;状态,另一种解决方法是在执行AcceptChanges之后调用EntityKey getter,这可确保正确设置EntityKey支持字段。例如,

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

答案 1 :(得分: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();
}

修改

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