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
|
Hi, I have trouble with single inheritance that the one to one relationship on the derived entity does not seem to work when I load the derived entity as part of another entity. The one to many relationship on the same entity on the other hand works fine. I have attached the model. When I load PostionRepo directly the collection is populated but ProductInformationRepo is missing. Somehow the data is not read. I just used the designer to create the relationships. I am bit lost why the data is not being populated. It is probably some key definition, but I was not able to figure out what I need to change. Do you have any hints? Cheers, Rob
|
|
|
Hi Rob, This appears to be a bug in our handling of the case where two derived entities have a property of the same name but mapped to different columns. In your case, the PositionRepo class has an association named ProductInformation, and hence a foreign key property named ProductInformationId, whose Column Name is set to ProductInformationRepoId. The PositionBond class also has an association named ProductInformation, and hence also has a foreign key property named ProductInformationId, but whose Column Name is set to ProductInformationBondId. The fact that the properties have the same names, but participate in the same table (because of STI), is causing a mixup with the column names inside LightSpeed. The workaround is to rename one or both of the associations, e.g. rename PositionBond.PositionInformation to PositionBond.PositionInformationBond. (If this is really inconvenient or undesirable there are lower-level workarounds but they require a bit more manual coding -- let me know if you need me to describe these.) Thanks for reporting this and please let us know if you still see problems. |
|
|
Cheers, Ivan! The simple workaround solved the problem. If you have time I would be interested in the lower-level solution. Awesome response time by the way! |
|
|
The lower-level solution involves bypassing the designer and getting hands-on with the LightSpeed class definitions. One of the cool features of LightSpeed is that, at the CLR level, our mapping operates on fields, not properties. The designer fudges this distinction because 99% of the time your properties are going to map directly to your database anyway and are just going to be wrappers for your fields. But what it means is that if you want to -- and don't mind bypassing the designer -- you can decouple your public API from your database mappings. Thus, you can write: private int _productInformationBondId; Note that you now get to refer to the FK in the public API as ProductInformationId (as you were wanting to in your current model), but you avoid the duplicate names bug because you can give the private backing field a different name in one of the classes. So, given that the designer autogenerates the backing field name from the property name, how do you do this without throwing out the designer and maintaining your entire model by hand? The answer is to write the fields and properties yourself in partial classes. But first you need to get rid of the designer autogenerated code. One way to do this is to delete the association out of the designer, but this is nasty because (a) it makes the association non-obvious to people looking at the diagram and (b) it messes up database synchronisation. So instead we provide an option just to suppress code generation. I'll show you how to do this in a moment, but before we suppress the generated code, we want to copy it. Here's what you need to do: * Pick which of the two associations you're going to rename the private backing field for (you need to do it only for one of the associations, though you can do it for both if you like). I'll use the PositionBond/ProductInformationBond association, and pretend that you *haven't* made the workaround change i.e. that the association is still called ProductInformation. * If you don't already have partial class files for the entities at both ends of this association, create them. (You can do this by hand or by right-clicking each entity and choosing Refactor > Create Partial Class.) * Open the generated code file (Model.cs). * Locate each entity involved in the association. Each entity will have a private EntityHolder<TheOtherEntity> member named for the backreference and a wrapper property of type TheOtherEntity. (E.g. PositionBond has a field EntityHolder<PositionInformationBond> _productInformation, and a property PositionInformationBond ProductInformation.) Additionally, one entity will have a foreign key member named for the backreference plus Id, and a wrapper property for this. (E.g. PositionBond has a field int _productInformationId and a property int ProductInformationId.) Copy all these fields and properties to the relevant partial classes. * Close the generated code file (Model.cs). * In the designer, select the association arrow, go to the Properties window, and change Generation to None. Save your changes. * Go into the partial class for the entity with the FK. (In this case PositionBond.) Now rename the EntityHolder and FK backing fields. You need to keep the _xxx/_xxxId convention but the xxx bit can be anything you like. E.g. change _productInformation to _bond and _productInformationId to _bondId. Update the properties accordingly (or use the VS Rename refactoring to do it for you.) * Go into the partial class for the entity without the FK, and change the name of the ReverseAssociation to match the changes above. E.g. in ProductInformationBond, on the _positionBond field, change the RA from "ProductInformation" to "Bond". * Save all changes and rebuild. I know this sounds a bit verbose and complicated but once you get your head around the relationship between the fields and properties, and how LightSpeed relates the two ends of the association, it should be pretty clear. It will probably make more sense once you're looking at the code! (Though you'll probably want to back up your working code first just in case!) And remember, you don't have to do this -- if you're okay with your existing workaround then feel free to stick with it, I'm presenting this primarily for information and to make you aware of the options and techniques. |
|
|
Awesome, I will give this a go when I have confirmation that we can use Lightspeed and I need to refactor the model.
Thanks a lot! |
|