This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Subj |
|
|
Hi jjanarth, Can you provide some more detail about which caching you are looking to disable? :) By default the 2nd level cache is not enabled, perhaps you are refering to entities returning from in memory during a unit of work?
Jeremy |
|
|
Hi Jeremy, Thanks for quick reply. Here is a simple example: var uow = ctx.CreateUnitOfWork();var user = uow.users.Where(p => p.Login == userid).FirstOrDefault();string Email = user.Email;
If I edit Email field in the database manually and then execute above code again, I get old value for Email until I do uow.SaveChanges(true); |
|
|
Yes - that's correct. By design the entity is loaded from the identity map if it has already been loaded within the current unit of work. This is to ensure you get the same entity back across multiple queries which may load it. To flush it, you need to clear the unit of work as indicated above with .SaveChanges(true) and then it will be reloaded from the database. If you are concerned about concurrency then you could look at using the LockVersion field on your entity which will cause LightSpeed to use optimistic concurrency when persisting any changes to the entity. From the docs: LockVersion Attribute – If a field called “LockVersion” (or _lockVersion etc.) is declared within an Entity, LightSpeed will automatically apply Optimistic Concurrency checking when saving entities of that type. LockVersion should be of type int, and the LockVersion database column should be a non-nullable integer.
Jeremy |
|
|
So no way to disable it in the settings or somehow else? I want to receive actual database data on every query. |
|
|
No not currently - however this has previously been asked for so we do have an item on our backlog to add in a flag when executing a query to have it refresh any items already in the identity map. For the time being, if you want to force a refresh of the entity you need to either fetch within the scope of a new unit of work, or flush the existing unit of work.
Jeremy |
|
|
+1 Just ran into this when executing a store proc to return entities. Calling stored proc and getting data from the result manually as a work around. |
|
|
I would also like to vote for the option of not having to call savechanges(true) to remove all of the objects from the UOW. I have a condition where I load up a series of objects, use them to perform some calculations and then I an done with the objects. I need to remove them from all collections or I will run out of memory. I have about 2-3 million objects that I need to process but never update. I am trying not to have to create a ton of UOW just to get around the issue. Thanks, Joe Feser |
|
|
Hi Joe, So you'd like some sort of function to unregister an entity from the unit of work? Basically so it reverts to a state as before the entity was associated with it? Something along the lines of a UoW.UnregisterEntity(Entity entity) type method? This would remove it both from the internal identity map (L1 cache) and the Cache if you've configured one (L2 cache)? I just want to better understand what you're trying to achieve here :-) John-Daniel Trask |
|
|
That seems like a clean way to do it, but it would also be nice to just reset everything to it was before it started. Here is my use case: I am working with Coverage trend file from a .NET coverage tool. Every time you run coverage on your assemblies, the information is stored along with the visit counts and statistics. The way the data is stored, you have the ability to obtain all of the types for an assembly during one execution or over multiple executions. The way I query the data, I may return 10 to 1000 items, but I may only walk a subset of those items. I want to make sure the items that ended up in the cache are removed when I call Reset() so that I do not have a memory issue. In my example, this would happen after you are done processing the data from an assembly. I want to make sure that everything is cleaned up and removed from the UOW. Does that help? Joe Feser |
|
|
I finally had to log out of my other account. :) |
|
|
Hi Joe, I've just added a UnitOfWork.Detach(Entity entity) method to LightSpeed. This will de-register the entity from the internal identity map. Currently it does not propogate the changes to any associated entities, let me know if this will be an issue as I may alter the method to allow you to specify if associated entities should be removed. This will be available in tomorrow's nightly build (available in approx. 6 hours). It will be dated the 29th of May. I hope that helps, John-Daniel |
|
|
John, Would an associated entity be something like an order detail for an order or a product for an order? Is it hard to perform a Clear() which is the same thing the savechanges(true) does internally? Speaking of savechanges(true), does it not detach the entity from the uow? Is this a feature? I stopped passing true but someone may want to understand how to check if the object is or is not part of the uow. Thanks, Joe |
|
|
Hi Joe, Currently Detach() simply deregisters that single entity. We could look at having it propgate those changes though. After much debate internally about this we've decided to try and discover a bit more about your situation before making a change. We're keen to look at this more deeply with LightSpeed 3.0 just because we have plans that would be a bit more invasive that exposing Reset(). Reset() shouldn't be exposed simply because we may in future want to do other tasks in here that folks may not want firing when calling this method. Also, The UoW is supposed to fairly simply manage entities so you don't have to worry about it so much. The plans are in an early stage but the idea of being able to potentially assign some sort of FetchPolicy or CachePolicy whereby you could specify the behavior of the UoW. This would be a somewhat large addition and hence the apprehension to just run ahead and add it without too much thought. What sort of issues are you having currently - is your application actually crashing? A million objects isn't too heavy so it shouldn't be causing that sort of issue (unless perhaps you have very large objects, perhaps with blob data). What's the impact here? Ivan mentioned you're using SQLite, is this correct? The only reason I ask is that if you're only doing some inspection of objects it could be more efficient to write a stored procedure to return the collated information that you require but SQLite wouldn't help here as it does not support them. I'm just trying to get a better handle on your situation to be as helpful as possible without making a quick but hacky change. Appreciate your thoughts and time on this, John-Daniel |
|
|
John, Wow I just spent 20 minutes writing up a reply and Firefox just crashed while I was typing and I lost it. I appreciate you spending the time to even think of a solution to my problem. I understand that just exposing items as public members can play havoc on the long term design of the application. I don’t want to be “that” customer that everyone remembers for the wrong reasons. :) We may want to take this conversation offline so I can explain more, but here is the basic idea of why I want reset or a “no tracking” option for my objects. I am looking for something that works like a disconnected recordset but has the power of your app if I need to attach items or create new items to be saved. The biggest issue I have is during a merge. I need to read a ton of data from the database, perform a bunch of math against it, create plot points for a graph and then throw the data out. Currently we have a data format that is all Xml and objects in memory, but for one feature we are moving to a more efficient format. As you have more builds and more things change, a few reports take longer and longer just to read the data in (xml). The hope is to resolve this issue. I never have to track these objects, but I want strongly typed items coming from a database without creating a T4 template or some other insane amount of custom code. The reason for SqLite is we needed a zero install portable format. It runs about 2.5x faster and 20-30% smaller for our solution. On your point about stored procs, is there a way with LS to provide a complete sql statement with joins and such and tell it to populate Entity y with the results? SqLite does not support stored procs, so I want to provide a sql statement with 5 joins. :) Does this help? Thanks again, Joe Feser |
|