Ошибка NHibernate (невозможно вставить дубликат ключа с уникальным индексом) - PullRequest
1 голос
/ 28 июля 2010

Клиент моего класса:

public class Client : Entity
{
    public Client()
    {
        ListClientObjectX = new List<ClientObjectX>();           
    }

    public virtual IList<ClientObjectX> ListClientObjectX { get; set; }
    ...
}

Мой класс ClientObjectX

public class ClientObjectX: Entity
{
    public ClientObjectX()
    {
        Client = new Client();
        ObjectX = new ObjectX();
    }

    public virtual Client Client { get; set; }
    public virtual ObjectX ObjectX { get; set; }
    public virtual string Name {get; set;}
    ...
 }

Моя таблица ClientObjectX имеет уникальный индекс с двумя столбцами (ClientID и ObjectXID): idxClientObjectX

Отображение клиента (свободно):

public class ClientMap : ClassMap<Client>
{
    public ClientMap()
    {
        Table("tblClient");

        Id(x => x.ID,"ClientID").GeneratedBy.Identity().UnsavedValue(0);

        HasMany<ClientObjectX>(x => x.ListClientObjectX)
        .Inverse()
        .Cascade.AllDeleteOrphan()
        .KeyColumns.Add("ClientID");           
    }
}

Так, например, при загрузке клиента, который имеет в ListClientObjectX один объект:

var client = new Repository<Client>().Load(2);

И удалил из ListClientObjectX этот объект:

client.ListClientObjectX.RemoveAt(0);

Пока нет сохранения / подтверждения. Теперь я добавляю объект в ListClientObjectX с тем же ClientID и ObjectXID:

client.ListClientObjectX.Add(test);

Когда я сохраняю это, я получаю ошибку:

 repCliente.SaveOrUpdate(client);

Невозможно вставить строку повторяющегося ключа в объект 'dbo.tblClientObjectX' с уникальным индексом 'idxClientObjectX'. Заявление было прекращено.

Зачем получать эту ошибку? Как я могу это исправить?

Спасибо

Ответы [ 2 ]

1 голос
/ 28 июля 2010

Вам необходимо установить для ссылки ClientObjectX.Client значение null, а также удалить его из коллекции. Удаление его из коллекции не делает его сиротой, поэтому оно не будет удалено при сбросе сеанса.

var objectX = client.ListClientObjectX[0];
client.ListClientObjectX.Remove(objectX);
objectX.Client = null;

Может быть, лучше разбить операцию на две транзакции; один удалить, а другой добавить объект с той же уникальной комбинацией. Я думаю, что вы напрашиваетесь на неприятности, если вы часто добавляете и удаляете объекты с одной и той же уникальной комбинацией в одной операции.

0 голосов
/ 28 июля 2010

Вместо этого вы можете рассмотреть отображение <set> для этой коллекции.Обязательно переопределите Equals () и GetHashCode () для вашего объекта ListClientObjectX.Это обеспечит уникальность дочерних объектов в коллекции и полностью исключит проблему добавления дубликатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...