A 1:1 relation

Posts   
 
    
chaimweb
User
Posts: 10
Joined: 12-Apr-2005
# Posted on: 30-May-2005 15:50:22   

I have 3 tables: 1- Entity 2- Person 3- BusinessEntity Both Person and BusinessEntity are related in a 1:1 relationship to Entity (Each have a EntityID field), where the common fields are stored like EntityID, GovID, etc. The designer lists a property called 'Entity' among the "Fields mapped on relations" for the PersonEntity. When putting a PersonEntity class on my form in design mode however, I do not receive a Entity property related to that Person entity when trying to bind my controls to the various required fields. In other words, in the dropdown box of the databinding propety for the Textboxes Text field, I can see all the PersonEntity fields and it's 1:n related collections listed but not the 1:1 related entity ?

Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 30-May-2005 18:38:25   

How have you specified the 1:1 relationship. If you are using SQL Server (not sure about the others) you need to add a Unique Constraint to the FK column that is part of the 1:1. If you only have a Unique Index, then you'll need to add the constraint and generated the code again.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 30-May-2005 18:39:35   

An entity implements ICustomTypeDescriptor, to prevent that all kinds of columns show up in a webgrid when you bind a collection of an entity to such a grid.

By default only the properties which are not marked with 'Browsable(false)', are enlisted, and the field mapped onto the 1:1 relation is marked with 'Browsable(false)', so won't show up.

The workaround for now is to use the reference of the related entity for the datasource, like PersonEntity.Entity, and bind to that entity, instead of binding PersonEntity.

I'll file this as an issue and will see if I can come up with a fix for this.

Frans Bouma | Lead developer LLBLGen Pro
susacd
User
Posts: 10
Joined: 15-Dec-2005
# Posted on: 02-Feb-2006 14:19:12   

It may sound silly, but I do need to see the fields mapped onto 1:1 relation. For example, I have EntityPatient which contains EntityCity, and I cannot directly bind my controls to Patient.City.Name in VS.NET 2005 (WinForms project) as it complains that there is no City property for the Patient object (of course, it is visible from the code window). Instead of this simple and elegant approach, I now have to instantiate a separate City object as a datasource for a separate BindingSource object, or to perform similar tricks. My questions are: - can the code generator (or templates) be changed to remove "Browsable(false)" on 1:1 fields (objects)? - what was the initial reason for attaching this attribute to 1:1 fields?

Thanks,

Denis

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 02-Feb-2006 14:31:01   

If the relation is healthy (appears in the LLBLGen Designer) Then you may use the designer and add a field "CityName" to the Person Entity (fields on related fields).

Then in your fetch code, add a prefetchPath to fetch the PersonEntity with its CityEntity. Use the CityName in your binding.

susacd
User
Posts: 10
Joined: 15-Dec-2005
# Posted on: 02-Feb-2006 18:43:24   

I'm afraid that is not acceptable, as it would defeat the whole purpose of using ORM tool like LLBLGen. If I understand correctly, you are suggesting "flattening" the object hierarchy by adding fields from the "child" object to the "parent" object.

This effectivelly means that I add redundant fields everywhere in my object model - if I later need to use zip code, I should "copy" it to the Person entity again. Field by field, and I would end up with bloated object model just for the purpose of binding.

Wouldn't it be better just to remove the Browsable(false) attribute? Or am I overseeing something really simple?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 03-Feb-2006 11:10:45   

susacd wrote:

It may sound silly, but I do need to see the fields mapped onto 1:1 relation. For example, I have EntityPatient which contains EntityCity, and I cannot directly bind my controls to Patient.City.Name in VS.NET 2005 (WinForms project) as it complains that there is no City property for the Patient object (of course, it is visible from the code window). Instead of this simple and elegant approach, I now have to instantiate a separate City object as a datasource for a separate BindingSource object, or to perform similar tricks. My questions are: - can the code generator (or templates) be changed to remove "Browsable(false)" on 1:1 fields (objects)? - what was the initial reason for attaching this attribute to 1:1 fields? Denis

It's a pain. The 'datasource' item in vs.net works different from the .NET 1.x approach, currently the code doesn't have support for that.

ICustomTypeDescriptor doesn't work well with datasource/bindingsource, which is a bug in vs.net 2005 and which they're not willing to fix before the next vs.net version. So I had to remove ICustomTypeDescriptor.

The Browsable(false) property is there because it otherwise shows up in asp.net grids with automatic column retrieval (list of patients in a collection bound to a grid, you'll then get a city column). The ITypedList implementation on the entity collection will filter it out, otherwise it won't.

You don't give muchcontext information, which is really unfortunate, because we can't help you without it. Are you using Selfservicing or adapter? Is patient in a grid and are you binding the City.Name property to a textbox?

Because if you have a single patient object, you can also just bind the patient.city to the control, and set the datamember to 'Name'

Frans Bouma | Lead developer LLBLGen Pro
susacd
User
Posts: 10
Joined: 15-Dec-2005
# Posted on: 03-Feb-2006 13:21:23   

OK, that is what I tought... I am using adapter. I'm working on a "detail" screen, so right now all patient info, including city name, is displayed in text boxes. Notice however that I will be using grids for the same type of hierarchy.

Using patient.city as you suggest unfortunatelly requires two separate BindingSource objects to be dragged to the form (one for the patient and the other for the city), and I have to manually synchronize them, which is a pain.

So I guess the only real solution is to allow us to remove "Browsable" attribute on 1:1 properties when generating code in LLBLGen. I don't see it in templates shipped with the program, is there any way I could do it? Right now I am using search/replace function in VS to do that, which is too error-prone.

Thank you very much,

Denis

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 03-Feb-2006 14:20:50   

susacd wrote:

OK, that is what I tought... I am using adapter. I'm working on a "detail" screen, so right now all patient info, including city name, is displayed in text boxes. Notice however that I will be using grids for the same type of hierarchy.

Using patient.city as you suggest unfortunatelly requires two separate BindingSource objects to be dragged to the form (one for the patient and the other for the city), and I have to manually synchronize them, which is a pain.

I understand.

So I guess the only real solution is to allow us to remove "Browsable" attribute on 1:1 properties when generating code in LLBLGen. I don't see it in templates shipped with the program, is there any way I could do it?

llblgenproinstallation folder\SharedTemplates\C#\entityAdapter.template line 776 for the m:1 relation and line 808 for the 1:1 relation.

Again, be aware that it might screw things up on other things with VS.NET or controls, as databinding is one big pool of misery and it often falls apart, for example because in ASP.NET it works completely different as in winforms, and the crackpots who cooked up databinding didn't realize that using an object in both situations might not work as expected.

Also, the patient.city.name bridge might not work in some controls (3rd party mostly) because they assume a datarelation and a datatable and don't use the normal ways of inspect what's bound to the control.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 19
Joined: 03-Feb-2006
# Posted on: 08-May-2006 12:26:26   

Hajo,

Did you fix a problem with 1:1 relations in SQL Server when unique constraint is not allowed because field can be set to NULL? I have plenty of 1:1 relations but all of them are recoginzed as 1:n relations.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 08-May-2006 16:48:46   

THe driver only understands unique constraints, not unique indexes. So if you don't have a unique constraint on the field, it can't be used as a 1:1 relation.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 19
Joined: 03-Feb-2006
# Posted on: 09-May-2006 10:41:01   

It means it is database dependent? Do you see any workaround? In one of the posts I've seen that you are going to extend IDE in order to solve this problem. Is it still valid?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 09-May-2006 10:52:21   

Pawel wrote:

It means it is database dependent? Do you see any workaround? In one of the posts I've seen that you are going to extend IDE in order to solve this problem. Is it still valid?

Of course it's database dependent, as it's DATA dependent: the UC is required to make the FK be unique so there's just one entity on the FK side for every PK value. Otherwise it can't result in a 1:1 relation. If the code thinks it's a 1:1 relation it expects just 1 entity on the FK side. If that's not the case, you'll get odd results at runtime, not something you want.

I decided not to solve this in the IDE at this point. The only thing that was added was manually setting a field to be a PK field, to be able to use entities based on views in relations.

Frans Bouma | Lead developer LLBLGen Pro