Silverlight 4.0 为什么EntityAspect.RemoveFromManager不能完全删除?

Silverlight 4.0 为什么EntityAspect.RemoveFromManager不能完全删除?,silverlight-4.0,devforce,Silverlight 4.0,Devforce,我正在使用Silverlight 4和DevForce 6.1.11.0 我有一些实现EntityAspect的POCO类 我使用WebClient从不同的设备获取这些实体。这些设备没有DevForce服务器。 将实体添加到实体管理器时,我首先使用entityManager.FindEntities(EntityState.AllButDetached)检查缓存中是否不存在具有该键的实体。然后我创建实体并添加它,如下所示: entityManager.AddEntity(entity); ent

我正在使用Silverlight 4和DevForce 6.1.11.0

我有一些实现EntityAspect的POCO类

我使用WebClient从不同的设备获取这些实体。这些设备没有DevForce服务器。 将实体添加到实体管理器时,我首先使用
entityManager.FindEntities(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);
//不返回任何内容
var instancesInManager=entityManager.findentials(EntityState.AllButDetached)。其中(i=>i.p_键1==41&&i.p_键2==5448);
//一无所获
var detachedInstancesInManager=entityManager.Findentialities(EntityState.Detached)。其中(i=>i.p_键1==41&&i.p_键2==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);
//返回实例,但没有一个实例具有带零的键或我要查找的键。
var instancesInManager=entityManager.findentials(EntityState.AllButDetached);
//不返回任何结果
var detachedInstancesInManager=entityManager.FindEntities(EntityState.Detached);
编辑2

使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.ComponentModel.DataAnnotations;
使用System.Runtime.Serialization;
使用IdeaBlade.Core.DomainServices;
使用IdeaBlade.EntityModel;
使用IbVal=IdeaBlade.Validation;
命名空间服务器模型
{
[DataContract(IsReference=true)]
公共类PocoSomeEntity:IKnownType、iHaspoEntityAspect、iNotifyProperty已更改
{
公共PocoSoMeetity(){}
专用int m_键1;
[关键]
公共int p_键1
{
获取{return m_key1;}
set{m_key1=value;OnPropertyChanged(“p_key1”);}
}
专用int m_键2;
[关键]
公共int p_键2
{
获取{return m_key2;}
set{m_key2=value;OnPropertyChanged(“p_key2”);}
}
...
#区域IHAspoEntityAspect成员
[显示(AutoGenerateField=false)]
[IgnoreDataMember]
public IdeaBlade.EntityModel.EntityAspect EntityAspect
{
得到;
设置
}
#端区
#区域INotifyProperty更改成员
/// 
///如果希望EntityManager自动侦听,则需要此接口实现
///任何财产变动。
/// 
公共事件属性更改事件处理程序属性更改;
受保护的无效OnPropertyChanged(字符串propertyName)
{
var handler=PropertyChanged;
if(处理程序!=null)
{
var args=新的PropertyChangedEventArgs(propertyName);
处理程序(this,args);
}
}
#端区
}
}

一种解决方法是使用FindEntity()进行双重检查。如果存在,则重新填充其属性并将其添加回manager

// 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();
}
//检查管理器中是否已存在实体
var instancesInManager=entityManager.findentials(EntityState.AllButDetached)。其中(i=>i.p_key1==key1&&i.p_key2==key2);
var entity=instancesInManager.FirstOrDefault();
if(实体==null)
{
PocoSomeEntity i;
//仔细检查管理器中是否确实存在实体:)
var doubleCheck=entityManager.FindEntity(新的EntityKey(typeof(PocoSomeEntity),key1,key2));
if(双重检查!=null)
{
i=(双重检查为PocoSomeEntity);
}
其他的
//如果它不存在,那么我们可以创建它
i=新PocoSomeEntity();
i、 p_key1=key1;
i、 p_key2=key2;
//填充或重新填充实体属性
...
实体管理器增编(i);
i、 EntityAspect.AcceptChanges();
}
编辑


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

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

有几个变通方法可能比您实现的Find逻辑更简单

  • 第一种是对这些POCO实体使用附加而不是添加/接受更改。当实体被附加为“Unchanged”时,代码路径DF会确保正确设置EntityKey

    manager.AttachEntity(entity);
    
  • 如果用例要求实体处于“添加”状态,那么另一种解决方法是在执行AcceptChanges之后调用EntityKey getter,这确保EntityKey backing字段设置正确。例如

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

我在测试中没有看到这个问题。如果EM缓存中已存在密钥,则在执行AddEntity()时将引发异常。在执行加法之前检查EntityKey的值-如果它是类似于0或tempid的值,可能有助于缩小问题范围,或者给我们m
 manager.AddEntity(entity);
 entity.EntityAspect.AcceptChanges();
 var ek = entity.EntityAspect.EntityKey;