Looks like this almost works..  Setting the initial ID to Guid.Empty
definitely makes the problem go away..  I also set the mapping as:

HasMany(x => x.Items)
   .KeyColumn("ShoppingListId")
   .Inverse()
   .Cascade.All();

Now I can add the item as such:

dbList.Items.Add(new ShoppingListItems
{
   Raw = source.Raw,
   UserId = identity.UserId
});

And it will create the new item.  However, one small problem: The new item
does NOT get linked to dbList.  Its ShoppingListId property is left as null.

Shouldn't adding a new item to dbList.Items make the ShoppingListId get set
to the primary key of dbList?  Or, do I have to manually specify this?
 Thanks!

Mike


On Tue, Jan 21, 2014 at 1:32 AM, Pete Appleton
<[email protected]>wrote:

> A few things that cross my mind:
>
>
>
> 1.  You'll definitely need an appropriate Cascade style for the "HasMany"
> mapping on ShoppingLists.Items, e.g. SaveUpdate - not sure which mapping
> system you're using, so don't know the exact syntax
>
> 2.  99% of the time, this mapping should be 'Inverse'
>
> 3.  It looks as you're manually assiging a new ID to the new
> 'ShoppingListItems' object, which I suspect is causing NH to believe that
> the new object is persistent.
>
>
>
> My general pattern for this sort of thing is as follows (pseudo-code for
> interesting bits only):
>
>
>
> class ShoppingList {
>
>    Guid Id { get; protected set; }
>
>    ISet<ShoppingListItem> Items { get; protected set; }
>
>
>
>   public ShoppingList() {
>
>     this.Items = new …
>
>   }
>
> }
>
>
>
> class ShoppingListLine {
>
>    Guid Id { get; protected set; }
>
>     public ShoppingList List { get; protected set; }
>
>
>
>   ShoppingListLine(ShoppingList list) {
>
>     this.List = list;
>
>     this.List.Items.Add(this);
>
>   }
>
>
>
>   void Delete() {
>
>     if(this.List != null) this.List.Items.Remove(this);
>
>     this.List = null;
>
>   }
>
> }
>
>
>
> var dbList = ….;
>
> var newItem = new
> ShoppingListLine(dbList);                                     // ctor
> handles association maintenance
>
>
>
>
>
>
>
> /Pete
>
> *From:* [email protected] [mailto:[email protected]] *On
> Behalf Of *Mike Christensen
> *Sent:* 21 January 2014 00:47
> *To:* nhusers
> *Subject:* [nhusers] Adding a new item to a collection using Fluent
> NHibernate doesn't INSERT the new row in the DB
>
>
>
> (StackOverflow question in case anyone wants 
> upvotes<http://stackoverflow.com/questions/21246584/adding-a-new-item-to-a-collection-using-fluent-nhibernate-doesnt-insert-the-new>
> )
>
>
>
> I have a model called `ShoppingLists` and each `ShoppingLists` has a
> collection of `ShoppingListItems` called `Items`.  What I would *like* to
> be able to do is add a new item to my list as such:
>
>
>
>     dbList.Items.Add(new ShoppingListItems(Guid.NewGuid(),
> identity.UserId, source.Raw));
>
>
>
> I would expect the `ShoppingListItems` to automatically be *linked* to its
> parent `ShoppingLists` class, and for NHibernate to create the appropriate
> SQL `INSERT` statement when the transaction is committed.  However, instead
> I get the exception:
>
>
>
>     NHibernate.StaleStateException was unhandled
>
>       HResult=-2146232832
>
>       Message=Unexpected row count: 0; expected: 1
>
>       Source=NHibernate
>
>
>
> What I have to do instead is create the object, save it, then add it to
> the collection:
>
>
>
>     var newItem = new ShoppingListItems(Guid.NewGuid(), identity.UserId,
> source.Raw);
>
>     newItem.ShoppingList = dbList;
>
>     session.Save(newItem);
>
>     dbList.Items.Add(newItem);
>
>
>
> I'd like to eliminate the need to do this.  My mappings for
> `ShoppingLists` is as such:
>
>
>
>     Id(x => x.ShoppingListId);
>
>
>
>     Map(x => x.UserId).Not.Nullable();
>
>     Map(x => x.Title).Not.Nullable();
>
>
>
>     HasMany(x => x.Items)
>
>        .KeyColumn("ShoppingListId")
>
>        .Cascade.Delete(); // If Shopping List is deleted, delete all the
> Items that reference this list
>
>
>
> And my mappings for `ShoppingListItems` is:
>
>
>
>     Id(x => x.ItemId);
>
>
>
>     Map(x => x.Raw).Length(50);
>
>     Map(x => x.Qty);
>
>     Map(x => x.Unit);
>
>     Map(x => x.UserId).Not.Nullable();
>
>     Map(x => x.CrossedOut).Not.Nullable();
>
>
>
>     References(x => x.Recipe).Column("RecipeId");
>
>     References(x => x.Ingredient).Column("IngredientId");
>
>     References(x => x.ShoppingList).Column("ShoppingListId");
>
>
>
> I've tried playing around with `Cascade.All()` on each, to no avoid.  Any
> ideas?
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/nhusers.
> For more options, visit https://groups.google.com/groups/opt_out.
>
> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/nhusers.
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to