Silverlight 4.0 为什么EntityAspect.RemoveFromManager不能完全删除?
我正在使用Silverlight 4和DevForce 6.1.11.0 我有一些实现EntityAspect的POCO类 我使用WebClient从不同的设备获取这些实体。这些设备没有DevForce服务器。 将实体添加到实体管理器时,我首先使用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
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;