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
|
I have a greenfields project that I believe is best approached with a fair whack of inheritance in both the C# objects and the tables in the database. Basically, as an example, I am implementing a number of 'contact'-based entities beginning with a base interface (that will be passed around when no functionality is required), an abstract implementation of a contact base class, and concrete implementations on top of the abstract class: individual and organisation. The reason for implementing it this way is due to the fact that an individual can be provided with the same services as an organisation, but they are clearly not the same. Now, on top of those more specific classes, I am also implementing individual and organisational debtor and creditor classes (which implement an interface IDebtor or ICreditor, respectively) An option that I considered was to just make all individuals and organisations debtors and creditors also, but this is not always the case, and often debtors and creditors are not using the services of the company, although they could. So, I would like the separation to exist in the code structure, but also in the database for future development. Ok, so I have come to this stage, and I plan to reflect the inheritance structure in the database, because they really are all separate types of entities. So my question is, is there any way that lightspeed can support all the layers of inheritance, both in the code AND database? It's quite a complex structure, but the idea is that a flexible structure be built for a customisable packaged solution, so the base tables will always exist, but specific client's requirements are also represented.
Cheers :) |
|
|
LightSpeed supports two inheritance models: single table inheritance and concrete table inheritance. In single table inheritance, the records for all kinds of X go into the same table, with a discriminator column to indicate their actual type. In your example, this would result in a Contact table, and you'd have to stuff both individuals and organisations into that table. From your description, this is unlikely to be a good way to design your database. In concrete table inheritance, each concrete class (and in LightSpeed CTI, a concrete class should normally be a leaf class) gets its own table, which contains all the columns for that concrete class. In your example, this would result in separate Person and Organisation tables. Common attributes (e.g. Name) would appear as columns in both tables. This probably does not count as representing inheritance within the database. (It also doesn't support query-time polymorphism.) There is a third kind of inheritance, which Fowler calls "class table inheritance," in which each class gets a table containing only its own fields. In your example there would be a Contact table containing, say, Name and Address, a Person table containing, say, EmailAddress, and an Organisation table containing, say, GSTRegistrationNumber; so the Person entity would have its data spread out across the Contact and Person tables. This is probably the closest to "modelling inheritance in the database." LightSpeed does not support this form of inheritance. If this is what you want in the database you would need to use some sort of composition relationship in the domain model, rather than inheritance, which is not what you want. So I suspect that LightSpeed can't support the inheritance model that you want in both code and database; but hopefully this discussion gives you a clearer idea of how LightSpeed may or may not relate to what you want, and perhaps you may be able to identify a suitable model where I haven't. I'd also suggest taking a look at http://www.mindscape.co.nz/blog/index.php/2009/03/01/getting-started-with-inheritance-in-lightspeed/ which describes our supported inheritance models in more detail. In addition, it may be worth exploring alternative approaches. You're obviously thinking about using interfaces to decouple a lot of this stuff anyway, so it may be possible to finesse the need for implementation inheritance in the code in favour of interfaces. I've bumped this over to a colleague who has recently worked on a project that had some similar concepts to yours and who may be able to give you some more concrete advice. |
|
|
Yeah, concrete table inheritance was an option, but I really wanted to have a set of default tables that could then be inherited from for specific client's needs (so if, out of the box, the application didn't meet their requirements, only the specifics needed could be added in a more specific ClientContactClass type scenario.) I do plan on using LightSpeed, so if anyone there had any ideas to go about it, I would be more than happy for some! Of course, if I work it out I will feedback to you guys. Cheers :) |
|
|
Coward I just read your post because I am also looking for a solution to the problem, you describe. I wonder if you have been able to find out anything more on this issue. Appreciate your response André |
|
|
To tell the truth I haven't really. At least not with Lightspeed. But I am getting there (between other jobs!) I am working on rolling my own layer to sit above lightspeed that uses a what I call a domain object context which represents a domain entity made up of the classes generated from the tables. The context ensures that all the data is loaded (well, the top level data - I lazy load the collections still) and that an overarching entity is available to the application. Basically the top level of my entity is essentially multi layered. Fun. I haven't decided yet, but one of these domain entities will probably exist as a wrapper class rather than being populated by the underlying objects, just to speed it up and so that I don't have to write horrendous logic to then push changes back to the database. I don't really want to say it here, but it is possible with the Entity Framework. It is finnicky at best though. It's easy enough to set up in the designer, but if you do something in the wrong order, you have to rewrite the table inheritance (in the form of attributes) to get it to work. And as the EF designer can't be generated from the connections window (no drag drop) it became increasinly annoying as I changed the tables (had to delete and restart the wizard every time.) |
|
|
Hey Thank you for the quick response. I really don't want to go an implement another layer between LS and my business logic. I was looking for a way to support various dbms and first hit the great iqtoolkit (http://blogs.msdn.com/mattwar/pages/linq-links.aspx). Since this seems like very early beta stage, I decided to look around for commercial solutions and so found LS, hoping that it would spare me a lot of work. But since I have to think about work arounds already at this early stage of testing, I get the feeling, LS might not be appropriate for us although it is great software. But I'm not giving up yet ;-) André |
|
|
Yeah, for every other instance, I think that Lightspeed is probably what you should use. For one, the designer is unmatched. I don't really like the way I am building the intermediate layer, but I have a bit of time on that particular project to play around with ideas. I am justifying my strategy by comparing it to a glorified ViewModel implementation where I still present the model to the view by an actual ViewModel, it's just that I present the Model to the ViewModel with my object context. There is the issue of losing all the O-O inheritance, which is what really concerns me with it... |
|
|
Hi guys, I just wanted to let you know where we are at on this. With the present LightSpeed architecture, class table inheritance looks like a significant piece of work. Oddly enough, the insert, update and delete operations look do-able, but select is very problematic because the assumption of "each select runs off one table" is fairly fundamental to LightSpeed's query mechanism. We might be able to provide you with some sort of interim solution where you did selects through a view (which performed the appropriate joins) and we could then insert, update and delete back through the underlying tables, but it would be pretty kludgy. And there would still be restrictions on how associations would work similar to concrete table inheritance, i.e. you would have to push associations down to the leaf level. (This is because associations are potentially polymorphic, and we have no way of determining whether a class table inheritance SomeBaseTable row has corresponding rows in any "derived" tables.) LightSpeed 3, however, will introduce some significant new support for join queries. I haven't really looked into this, but I suspect this will make it a lot easier to cleanly implement class table inheritance. So I'm reluctant to try to tackle this on the existing code base -- I'd rather wait until LightSpeed 3 is out the door. This isn't a promise that we will work on this feature after LS3, though -- after all, we have finite resources and we have to prioritise. I know this doesn't really help you guys with your immediate projects but I just wanted to let you know that we are listening to this discussion and we are keeping the feature in mind, and to explain what our current thinking is and the kind of timescales we might be thinking about. |
|