I already fixed this, and it has been committed to svn.
DataContext.SetEntitySetQueries() was being called because of
DataContext._GetOrRegisterEntity(), which in turn was called by
DataContext.Register(), which was called by DataContext.SubmitChanges().
(Just check the callstack in the original message...) The problem was
twofold: (1) DbLinq's EntitySet<T> was screwy (though I blame a lot of
that screwiness on .NET's EntitySet<T> -- see the new EntitySetTest.cs
file, and laugh hysterically when you see when the
EntitySet<T>.ListChanged event is raised), and (2) calling
dinner.RSVPs.Add(rsvp) caused the EntitySet<RSVP> source to be created,
and EntitySet<T>.SetSource() cannot be called again once
EntitySet<T>.HasLoadedOrAssignedValues is true. Since
DataContext.SetEntitySetsQueries() tried to do just that, it threw an
exception.
Now I'm working on a related bug: subsequent updates aren't tracked. To
wit:
Dinner dinner = new Dinner {...};
RSVP rsvp = new RSVP();
rsvp.AttendeeName = User.Identity.Name;
dinner.RSVPs.Add(rsvp);
db.Dinners.InsertOnSubmit(dinner);
db.SubmitChanges();
// The above now works. Now...
RSVP rsvp2 = new RSVP();
rsvp2.AttendeeName = "whatever";
dinner.RSVPs.Add(rsvp2);
db.SubmitChanges();
// rsvp2 is NOT submitted to the database.
I'm still tracking down why this happens. The attached patch file
recreates this same scenario within the unit tests, and also
(thankfully) fails.
What I would appreciate is if you could look into the cache issues that
I'm seeing. :-)
Thanks,
- Jon
On Sun, 2009-05-10 at 23:41 +0100, Giacomo Tesio wrote:
> I think this is due to the "dinner.RSVPs.Add(rsvp);" line where you
> actually fill the EntitySet.
>
> The DataContext.SetEntitySetQueries() should not run on just inserted
> entity, since they are yet filled.
>
>
> Tomorrow I'll try to fix this...
>
>
> Giacomo
>
>
>
> On Fri, May 8, 2009 at 4:59 AM, Jonathan Pryor <[email protected]>
> wrote:
>
> Still continuing with my "NerdDinner on Mono" effort, and
> hitting the following issue:
>
> When I attempt to add a new Dinner, NerdDinner effectively
> does:
>
> Dinner dinner = new Dinner {...};
> RSVP rsvp = new RSVP();
> rsvp.AttendeeName = User.Identity.Name;
> dinner.RSVPs.Add(rsvp);
> db.Dinners.InsertOnSubmit(dinner);
> db.SubmitChanges();
>
> This fails, with:
>
> System.Reflection.TargetInvocationException: Exception has
> been thrown by the target of an invocation. --->
> System.InvalidOperationException: The EntitySet is already loaded and the
> source cannot be changed.
> at
> System.Data.Linq.EntitySet`1[NerdDinner.Models.RSVP].SetSource (IEnumerable`1
> entitySource) [0x00000]
> at (wrapper managed-to-native)
> System.Reflection.MonoMethod:InternalInvoke
> (object,object[],System.Exception&)
> at System.Reflection.MonoMethod.Invoke (System.Object obj,
> BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[]
> parameters, System.Globalization.CultureInfo culture) [0x000ca] in
> /home/jon/Development/mono-HEAD/mcs/class/corlib/System.Reflection/MonoMethod.cs:169
>
> --- End of inner exception stack trace ---
> at System.Reflection.MonoMethod.Invoke (System.Object obj,
> BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[]
> parameters, System.Globalization.CultureInfo culture) [0x000e5] in
> /home/jon/Development/mono-HEAD/mcs/class/corlib/System.Reflection/MonoMethod.cs:179
>
> at System.Reflection.MethodBase.Invoke (System.Object obj,
> System.Object[] parameters) [0x00000] in
> /home/jon/Development/mono-HEAD/mcs/class/corlib/System.Reflection/MethodBase.cs:111
>
> at System.Data.Linq.DataContext.SetEntitySetsQueries
> (System.Object entity) [0x00173] in
> /home/jon/Development/mono-HEAD/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs:608
>
> at System.Data.Linq.DataContext._GetOrRegisterEntity
> (System.Object entity) [0x00015] in
> /home/jon/Development/mono-HEAD/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs:468
>
> at System.Data.Linq.DataContext.Register (System.Object
> entity) [0x0000d] in
> /home/jon/Development/mono-HEAD/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs:675
>
> at System.Data.Linq.DataContext.SubmitChanges (ConflictMode
> failureMode) [0x000a6] in
> /home/jon/Development/mono-HEAD/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs:378
>
> at System.Data.Linq.DataContext.SubmitChanges () [0x00000]
> in
> /home/jon/Development/mono-HEAD/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs:339
>
> at NerdDinner.Models.DinnerRepository.Save () [0x00000]
> at NerdDinner.Controllers.DinnersController.Create
> (NerdDinner.Models.Dinner dinner) [0x00000]
>
> Suffice it to say, this doesn't happen under .NET's
> System.Data.Linq. I'm wondering if anyone has seen a similar
> error to this before, and/or knows what an appropriate fix
> would be.
>
> Thanks,
> - Jon
>
>
>
>
>
>
>
>
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"DbLinq" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/dblinq?hl=en
-~----------~----~----~----~------~----~------~--~---
Index: src/DbLinq/Test/Providers/WriteTest.cs
===================================================================
--- src/DbLinq/Test/Providers/WriteTest.cs (revision 1069)
+++ src/DbLinq/Test/Providers/WriteTest.cs (working copy)
@@ -786,9 +786,22 @@
db.Categories.InsertOnSubmit(category);
db.SubmitChanges();
+ var p2 = new Product
+ {
+ Discontinued = true,
+ ProductName = "Another Test Product",
+ };
+ category.Products.Add(p2);
+ db.SubmitChanges();
+
+ Assert.AreEqual(1, db.Products.Where(p => p.ProductName == "Another Test Product").Count());
+
db.Products.DeleteOnSubmit(product);
+ db.Products.DeleteOnSubmit(p2);
db.Categories.DeleteOnSubmit(category);
db.SubmitChanges();
+
+ Assert.AreEqual(0, db.Categories.Where(c => c.CategoryName == "My New Category").Count());
}
}
}