Получение "Сущность с такой же идентичностью уже существует в этом EntitySet", но EntitySet пуст - PullRequest
3 голосов
/ 12 мая 2010

Когда я пытаюсь добавить новый элемент в мой EntitySet, я получаю следующее исключение:

Сущность с такой же идентичностью уже существует в этом EntitySet

Однако, когда я проверяю EntitySet, его количество равно 0.

Есть идеи, почему я получаю эту ошибку, когда набор пуст? Как может сущность уже существовать в наборе, если в наборе нет предметов?

UPDATE

Я сузил это немного больше. Это происходит только в том случае, если я добавляю элемент в набор, удаляю его, а затем снова добавляю. Даже если предмет больше не находится в 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; }
}

Клиентская GetIdentity () для PhotoDestinationDto:

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

6 голосов
/ 25 июля 2010

Juding по вашему коду Unit = selectedUnit и p.Destinations.Add(dest); и другим симптомам, которые вы описываете, похоже, у вас точно такая же ситуация. Мои выводы ниже исправили проблему для меня.

Заинтересован также, если в результате у вас возникли дублированные объекты в вашей базе данных. я получал строки, которые ранее были сохранены волшебным образом, превращаясь в New, а затем становился дурацкой записью. Снова это простое изменение ниже исправило это.


Существует обнаруженное мною условие гонки, которое может выдать эту ошибку, если вы создаете сущность и немедленно назначаете ей отношения внешнего ключа перед добавлением родительской сущности в ее набор сущностей.

Оказывается, сам акт установки отношения внешнего ключа фактически добавляет сущность к соответствующему набору сущностей, но иногда вызывает состояние гонки, особенно если ваш пользовательский интерфейс загружает и сохраняет и очищает наборы сущностей.

плохо

var todo = new TODO();
todo.Status = TODOContext.Statuses.Single(x=>x.Status == "Unknown");
todo.AssignedTo = TODOContext.Users.Single(x=>x.UserName == "JSMITH");
TODOContext.TODOs.Add(todo); // adding entity after setting FK

хорошая:

var todo = new TODO();
TODOContext.TODOs.Add(todo); // add entity before setting FK
todo.Status = TODOContext.Statuses.Single(x=>x.Status == "Unknown");
todo.AssignedTo = TODOContext.Users.Single(x=>x.UserName == "JSMITH");
3 голосов
/ 14 мая 2010

Хорошо, увидев ваш код, я вижу проблему. При удалении из EntityCollection сущность на самом деле не удаляется (как при отложенном удалении) - связь только разрывается, и для FK устанавливаются значения по умолчанию. Таким образом, ваш вызов photo.Destination.Remove () фактически не удаляет сущность из DomainContext (ctxt.PhotoDestinationDtos EntitySet). Вот почему вы столкнулись с кешем.

Чтобы действительно удалить его, вы должны вызывать ctxt.PhotoDestinationDtos.Remove.

1 голос
/ 13 декабря 2011

Любой, кто все еще получает эту ошибку, после попытки вышеуказанных исправлений я все еще получал ошибку. Наконец, я могу исправить это, назначив новый уникальный идентификатор моему идентификатору, даже если он не будет обновлен в базе данных.

1 голос
/ 30 августа 2011

У меня была такая же проблема, позже я понял, что в базе данных есть строка, в которой столбец идентификатора был "0", каждый раз, когда мы пытаемся сохранить новую запись, она изначально вставляет ее с 0 в столбце идентификатора, я удаляю тот, который уже присутствует, и мой код работал отлично, Я не изменил метод Inser, созданный классом DomainService,

0 голосов
/ 08 августа 2013

Когда вы удаляете сущность из EntitySet, соответствующая запись в базе данных должна быть удалена во время SubmitChanges (). По этой причине объект должен продолжать отслеживать объект - даже после того, как он был удален. Требуется для генерации оператора удаления.

Хотя он больше не доступен непосредственно в EntitySet (узел просмотра результатов на рисунке ниже), сущность отслеживается в частном свойстве _IdentityCache. В приведенном ниже примере у меня есть только одна сущность в EntitySet ...

enter image description here

... однако в свойстве _identityCache есть два элемента.

enter image description here

Вы можете получить доступ к объектам, отслеживаемым EntitySet, для которых EntityState удален, используя следующий код.

entitySet.EntityContainer.GetChanges().RemovedEntities

В вашем случае вам следует либо повторно использовать существующую сущность в коллекции RemovedEntities сверху, либо отсоединить ее перед добавлением новой сущности с тем же ключом.

0 голосов
/ 12 мая 2010

Вы удостоверились, что у вас есть PK / идентификатор, правильно определенный в вашей БД в этой таблице, и это отражено в вашей модели? Попробуйте переопределить OnError в вашем DomainService, чтобы получить больше информации об исключении на стороне сервера. (Вы получаете эту ошибку на стороне клиента / Silverlight, верно?)

...