2012-06-08 3 views
7

Sto facendo alcuni test utilizzando NHibernate e attualmente ho due entità mappate, Ordini e Prodotti. Come sempre un Ordine ha una collezione di prodotti, e sto mappatura questo come:Perché NHibernate elimina e ricrea tutte le associazioni in una raccolta quando aggiungo un articolo ad esso?

<bag name="Products" cascade="all" lazy="true"> 
    <key column ="Order_ID" /> 
    <many-to-many class="Product" column="Product_ID" /> 
</bag> 

E sul lato C#:

public virtual IList<Product> Products 
{ 
    get { return _Products; } 
    set { _Products = value; } 
} 
private IList<Product> _Products = new List<Product>(); 

Nel caso ho una persistito Ordine (ordine di John) nel database con alcuni articoli nella sua collezione di prodotti (una mela, un'arancia e una noce di cocco) e provo ad aggiungere un nuovo oggetto alla raccolta (una banana) che posso vedere dall'output SQL t cappello NHibernate sta facendo qualcosa di simile:

INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID) 
DELETE FROM Products WHERE Order_ID = @Johns_Order_ID 
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Apple_ID) 
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Orange_ID) 
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Coconut_ID) 
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Banana_ID) 

Invece di limitarsi a fare qualcosa di simile:

INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID) 
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Banana_ID) 

Allora perché NHibernate cancellare tutte le associazioni dei Prodotti tavolo per ricreare nuovamente quando ho' sto solo cercando di inserire un nuovo prodotto in esso? Come evitarlo?

Grazie in anticipo!

PS: Ho cercato di usare il inversa attributo mappatura come suggerito in questo SO Question ma anche se il nuovo prodotto viene salvato la sua associazione con un ordine non lo fa.

EDIT:

Ecco il codice che sto usando per modificare la lista dei prodotti:

Order order = session.Load<Order>(orderId); 
order.Products.Add(new Product() { Name = "Banana" }); 
using (ITransaction transaction = session.BeginTransaction()) 
{ 
    session.Update(order); 
    transaction.Commit(); 
} 
+0

Puoi mostrare il codice per modificare l'elenco dei prodotti – dotjoe

+0

Ciao, ho modificato la mia domanda per includere il codice che sto usando per modificare l'elenco dei prodotti come suggerito. –

risposta

5

C'è già una domanda simile su SO: NHibernate Many-To-Many Is Deleting All Associations Before Inserting

Da NHibernate di documentation:

Le borse sono il caso peggiore. Poiché un sacchetto consente valori di elementi duplicati e non ha una colonna di indice, non è possibile definire alcuna chiave primaria. NHibernate ha nessun modo di distinguere tra righe duplicate. NHibernate risolve il problema rimuovendo completamente (in un unico DELETE) e ricreando la raccolta ogni volta che cambia. Questo potrebbe essere molto inefficiente con .

+0

Grazie per la tua risposta, e mi dispiace di non essere stato in grado di trovare da solo quella domanda simile. Ora ho cambiato la mia mappatura in un ** idbag ** invece che in un ** bag ** e tutto funziona come un incantesimo! –