获取“此EntitySet中已存在具有相同标识的实体”,但EntitySet为空

时间:2010-05-11 20:34:45

标签: silverlight silverlight-4.0 wcf-ria-services

当我尝试向我的EntitySet添加一个新项目时,我遇到了这个异常:

  

具有相同身份的实体   已存在于此EntitySet

但是,当我检查EntitySet时,它的计数为0。

任何想法为什么当集合为空时我会收到此错误?如果集合中没有项目,实体如何已存在?

更新

我把它缩小了一点。只有在我将项目添加到集合中,删除它,然后重新添加它时才会发生这种情况。即使该项目不再在EntitySet中,它仍然以某种方式记住它。我需要做些什么来让它忘记?

更新:以下是所涉及的类和逻辑的一些代码段。

服务器实体:

public class PhotoDto
{
    [Key]
    [Editable(false)]
    public int Id { get; set; }

    /* clip */

    [Include]
    [Association("Photo_Destination", "Id", "PhotoId")]
    public EntitySet<PhotoDestinationDto> Destinations { get; set; }
}

public class PhotoDestinationDto : BaseDestionationDto
{
    [Key]
    [Editable(false, AllowInitialValue = true)]
    public int PhotoId { get; set; }

    [Key]
    [Editable(false, AllowInitialValue = true)]
    public bool IsAnnotated { get; set; }

    [Key]
    [Editable(false, AllowInitialValue = true)]
    public int DropZoneId { get; set; }
}

public class BaseDestinationDto
{
    [Key]
    [Editable(false, AllowInitialValue = true)]
    public Guid DatabaseUid { get; set; }

    [Key]
    [Editable(false, AllowInitialValue = true)]
    public string Unit { get; set; }

    [Key]
    [Editable(false, AllowInitialValue = true)]
    public string EqCircId { get; set; }

    [Key]
    [Editable(false, AllowInitialValue = true)]
    public string EqType { get; set; }
}

PhotoDestinationDto的客户端GetIdentity():

/// <summary>
/// Computes a value from the key fields that uniquely identifies this entity instance.
/// </summary>
/// <returns>An object instance that uniquely identifies this entity instance.</returns>
public override object GetIdentity()
{
    if ((((this._eqCircId == null) 
                || (this._eqType == null)) 
                || (this._unit == null)))
    {
        return null;
    }
    return EntityKey.Create(this._dropZoneId, this._eqCircId, this._eqType, this._isAnnotated, this._photoId, this._unit, this._databaseUid);
}

删除照片目标客户端:

PhotoDto photo = GetPhotoDto();
PhotoDestinationDto destToRemove = photo.Destinations.First(x => x.DropZoneId == 1);
photo.Destinations.Remove(destToRemove);

添加照片目标客户端:

var dest = new PhotoDestinationDto
{
    DropZoneId = zoneId,
    EqCircId = selectedEqCircId,
    EqType = selectedEqType,
    Unit = selectedUnit,
    PhotoId = id,
    DatabaseUid = selectedDatabaseId
};

p.Destinations.Add(dest); // this is where exception is thrown. p.Destinations.Count is 0 here.

6 个答案:

答案 0 :(得分:6)

答案 1 :(得分:3)

好的,看到你的代码后我就看到了问题。从EntityCollection中删除时,实际上并未删除实体(如在挂起的删除中) - 仅关闭关联,并将FK设置为​​其默认值。所以你的photo.Destinations.Remove()调用实际上并没有从DomainContext(ctxt.PhotoDestinationDtos EntitySet)中删除实体。这就是你得到缓存冲突的原因。

要实际删除它,您应该调用ctxt.PhotoDestinationDtos.Remove。

答案 2 :(得分:1)

我有同样的问题,我后来发现数据库中有一行ID列为“0”,每当我们尝试保存新记录时,它最初在ID列中插入0,我删除了已存在的那个,我的代码工作得非常好, 我没有更改DomainService类创建的Inser方法

答案 3 :(得分:1)

任何仍然遇到此错误的人,在尝试上述修复后我仍然收到错误。最后,我可以通过为我的身份ID分配一个新的唯一ID来修复它,即使这不会在数据库中更新。

答案 4 :(得分:0)

您是否确保在该表的数据库中正确定义了PK /身份,并且它会反映在您的模型中?尝试覆盖DomainService中的OnError以获取有关服务器端异常的更多信息。 (你在客户端/ Silverlight端遇到此错误,对吗?)

答案 5 :(得分:0)

从EntitySet中删除实体时,应在SubmitChanges()期间删除数据库中的关联记录。出于这个原因,实体必须继续跟踪实体 - 即使它已被删除。它是生成删除语句所必需的。

虽然它在EntitySet中不再可用(下图中的Results View节点),但在私有_IdentityCache属性中跟踪该实体。在下面的示例中,我在EntitySet中只有一个实体...

enter image description here

...但是_identityCache属性中有两个项目。

enter image description here

您可以使用以下代码访问具有EntityState of Deleted的EntitySet跟踪的实体。

entitySet.EntityContainer.GetChanges().RemovedEntities

在您的情况下,您应该重新使用上面的RemovedEntities集合中的现有实体,或者在添加具有相同密钥的新实体之前将其分离。