Collections and OneToMany

Feb 28, 2016 at 7:55 AM
I was doing some tests with my entities
using (var opContext = AppManager.GetOperationContext(USER))
            {
                var sessionOne = opContext.OpenSession();

                var user = sessionOne.NewUtente("llusetti", "prova", "Luca Lusetti");
                var connection = sessionOne.NewConnessione("cond.asp", "h2_vsdev", "ll", "ll", "test", "test");

                connection.UTENTE = user;                       

                sessionOne.SaveChanges();                

                Assert.IsTrue(user.CONNESSIONI.Count == 1);                

                var sessionTwo = opContext.OpenSession();

                var userFromSessionTwo = sessionTwo.GetEntity<dgk_utente>(user.id);
                sessionTwo.DeleteEntity(userFromSessionTwo.CONNESSIONI[0]);
                sessionTwo.SaveChanges();                                
                
                Assert.IsTrue(userFromSessionTwo.CONNESSIONI.Count == 0);

                sessionTwo.DeleteEntity(userFromSessionTwo);
                sessionTwo.SaveChanges();
            }
I was expeting the last assert to be true but when I delete the collection it is not removed from the user.CONNESSIONI collection.

Is this the expected thing or am I missing something ? The user has a collection defined like this (OneToMany is just for clarity)
[OneToMany]
IList<dgk_utente_connessione> CONNESSIONI { get; }
Coordinator
Feb 28, 2016 at 8:29 AM
that's expected behavior. It is possible to do this adjustment automatically, but I made a conscious decision not to do it. Here's the reason - doing these adjustments in lists would require some substantial work at the end/after SaveChanges, running around and inspecting/refreshing entities etc; plus additional tracking while you're doing deletes. On the other hand, there's a big chance that nobody cares about this.
At least in web apps, a typical controller action is: server receives DELETE request, loads entity (or entities), deletes it, calls SaveChanges and returns OK to the client. Nobody cares what's left in the entity session or still loaded entities, they are left to be garbage collected, so any extra activity would be a waste. If your operation is more complex and you want to continue operations, you can always remove an entity from the list explicitly. Or reload list.
that's the reasoning
Roman
Coordinator
Feb 28, 2016 at 8:36 AM
basically list properties give you smart lazy loading of related entities, but do not promise any automatic adjustments when you modify these related entities. Not too smart. There's even more complex case, with ordered list, when there's OrderBy attribute on child entity - list property is sorted appropriately. Now imagine you modify child entities so that one of the sort fields changes. Should the list re-sort automatically? and so on,...
so - automatic load, but from this point you're on your own
Feb 28, 2016 at 9:12 AM
Sounds good to me, now that i know it :)
Feb 29, 2016 at 11:56 PM
crazy refactoring tonight, can you explain the filter syntax ?
I've used "canc = 0" in my test but I've seen tha tyou used {Category} = 1.
How can I put an and condition in it ?
Coordinator
Mar 1, 2016 at 12:02 AM
Edited Mar 1, 2016 at 4:56 AM
filter is just plain SQL expression; place holders like {propname} will be replaced by engine with fully qualified column name for 'propname' property; and it will be added with AND to whatever filter in WHERE is already there. So use AND or whatever is supported by MS SQL; don't forget to enclose in parenthesis if it's complex expression (especially with OR)

Note that you need to use curly brace syntax, because for LINQ statements the column might/should be referenced with table alias - if it is a join and table has alias. That's what engine would do as well. But if you use just column name directly, without braces, this SQL would fail.