NHibernate错误(无法插入具有唯一索引的重复键)

时间:2010-07-28 14:54:12

标签: nhibernate fluent-nhibernate

我的班级客户:

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

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

My Class 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表有一个唯一索引,包含2列(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 个答案:

答案 0 :(得分:1)

除了将其从集合中删除之外,还需要将ClientObjectX.Client引用设置为null。从集合中删除它不会使它成为孤儿,因此在刷新会话时不会删除它。

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

将操作分解为两个事务可能是个更好的主意;一个要删除,另一个要添加具有相同唯一组合的对象。如果您经常在一次操作中添加和删除具有相同唯一组合的对象,我认为您会遇到麻烦。

答案 1 :(得分:0)

您可能需要考虑此集合的<set>映射。一定要在ListClientObjectX对象上重写Equals()和GetHashCode()。这将确保集合中子对象的唯一性,并将完全避免添加重复项的问题。