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
|
Previously I had used triggers and SQL Server specific functionality to detect changes and deletion to data in a database, and log all the changes to a single AuditLog table. Now I am using LS, and plan to allow users to use alternate databases, I need to move this functionality back into my code, as not all databases support the same functionality as SQL Server with regard to triggers, and detecting changes. My database have almost one hundred tables, so I don't want to have to manually create function for each table class, so I was wondering if anyone had come up with a solution, that uses the functionality built into LS3.0, to produce a single function / override that would enable me to catch all saves / changes / deletes etc. and thus allow mw to format them and save them to the AuditLog table. Any and all advice is welcomed. |
|
|
Hi Mark, Have a look at the Change Tracking feature in LightSpeed 3. While it isnt a turnkey auditing solution, it would be fairly easy for you to implement a custom auditing solution based on the information provided. Have a look at the blog post we put out on LightSpeed 3 (http://www.mindscape.co.nz/blog/index.php/2009/12/14/lightspeed-3-0-released/) for some more information and give us a yell if you have any more questions about this feature :)
Jeremy |
|
|
Hi Jeremy, Thanks for the reply. I have taken a look at these features, but, unless I am mistaken, they operate at a uow level. I was hoping for something further up the chain, something generic to all tables. I will have to look deeper into this when I get a little more time, in the meanwhile, I will continue to use my existing method, which uses SQL Server triggers. It just means it will be while before I can port the database to another platform. Thanks
Mark |
|
|
One option is to create a common base class for your entities, derived from Entity<TId>, and override OnPropertyChanged and OnEntityStateChanged. This should catch all creation, edit and delete events. |
|
|
Hi Ivan, that looks more like what I need. But being very new to LS, if I override the Entity<Tld> as you suggest, would it not overwrite all my changes the next time I Refresh from Source Database? or do I need to buy the source code for this. I am alway wary of changing source code as it makes it difficult when I want to perform updates to LS later. |
|
|
Don't worry, you'll be okay as long as you put the overrides in a partial class. All the generated classes are marked as partial, which means you can add members to them in a separate file, and the various "bits" of the definition will be merged together by the compiler: // in your own file, e.g. MyEntity.cs As a shortcut, you can quickly create a partial class by right-clicking an entity in the designer and choosing Refactor > Create Partial Class. |
|
|
Uh, the above applies to per-class overrides. You actually probably want a common base class, and since the entity base classes are specified in the generated code, you have to do this slightly differently. There are two ways to do so. The first way is to create the base class in the designer (with no properties), and have everything inherit off it using Concrete Table Inheritance. Then use a partial class as discussed before to add your overrides to the base class. This is most convenient for database sync, but adds clutter to the diagram, and isn't usable if you have different ID types. The second way is to create an "external" base class, i.e. in code rather than the designer, and inherit off that. This avoids lots of inheritance arrows on the diagram, but will result in the designer continually reminding you that you might have put persistent fields in the base class and that if you have done so you'll have to sync them manually. (These warnings are benign: the designer will still get the sync right as long as you don't put persistent fields in the base class.) If you choose the second option, here's how to do the inheritance: First, go to the LightSpeed Model Explorer (View > Other Windows if it's not already showing). Right-click the model node and choose Add New External Class Reference. Enter the fully qualified type name (e.g. MyCompany.MyProject.EntityBase). If your class inherits from a specific ID type e.g. from Entity<int>, enter that into the Identity Type box; if your class is generic e.g. EntityBase<TId> : Entity<TId>, set Identity Type to Generic. Second, select each entity on your diagram and go to the properties window. Find the Base Class setting and set it to your custom base class. Save your changes and check the generated code. You should now see that the generated entity classes are inheriting off the custom base class. |
|
|
Hi Ivan, Thanks for the explanation above. I have to say, all of the options seem a little long winded, and we have a lot of tables, hence entities, in our model. Is there any chance you will be putting this sort of auditing functionality into Lightspeed in the future? If not, it will need to go on my "to look at when have more time" list. Anyway, thanks again for you help, and understanding.
|
|
|
We have no immediate plans for this. It's something we know quite a few people are doing, so we do keep it in mind as a possible future feature. Against that is the variety of possible auditing requirements, which could make it quite complicated to implement -- we would probably have to restrict ourselves to a specific convention based approach. |
|
|
Hi guys, sorry for a late intrusion into the topic (just got about reading old posts from last month). I just wanted to share with MarkLFT our approach on getting auditing from LS. Instead of messing with all entities, we have an inherited UnitOfWork (actually something more like a factory class). So in this class, we have SaveChanges() method which does the auditing bit and calls also base LS UOW SaveChanges(). Within this method, we are using LS Change Tracking feature, but also some reflection for some scenarios, but all-in-all rather small amount of code, and has been working nicely so far. Of course, the trick is also that the whole application is using "our" UoW factory class, but this is something we planned from start, and prooved worthwile for auditing and some other features. |
|
|
Hi Marko, Thanks for the feedback. What you have done sounds like a perfect solution for what I need, would it be very cheeky of me to ask if I can have a sample of the code you used so I can use it as a starting point to develop a similar solution? Many thanks, Mark
|
|