Fields mapped onto related fields are not marked nullable

Posts   
 
    
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 22-Dec-2015 21:42:04   

Hi,

Taking this schema:


CREATE TABLE [dbo].[t](
    [a] [int] IDENTITY(1,1) NOT NULL,
    [b] [int] NULL,
 CONSTRAINT [PK_t] PRIMARY KEY CLUSTERED 
(
    [a] ASC
)

GO
/****** Object:  Table [dbo].[t2]   Script Date: 22/12/2015 15:36:13 ******/
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[t2](
    [pk] [int] IDENTITY(1,1) NOT NULL,
    [fk] [int] NULL
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[t2]  WITH CHECK ADD  CONSTRAINT [FK_t2_t] FOREIGN KEY([fk])
REFERENCES [dbo].[t] ([a])
GO

Table t has 2 columns, the primary key (column a) and another nullable int (column b). Table t2 has a FK (column fk) into table t which is nullable. The relation is optional.

In llblgen designer 4.2 Final July 21st, 2015, I reverse engineer this to 2 entities and in entity T2 add a field mapped onto a related field to add another fields for T.B. This is added as an int not an int? . Project attached. Why is that?

Thanks,

Scott

Attachments
Filename File size Added on Approval
relatedfieldtest.llblgenproj 9,801 22-Dec-2015 21:42.17 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 23-Dec-2015 11:01:59   

It's added as int and not int? as the nullability is reflected in the 'Optional' property of the field. 'fk' is marked as 'optional' as you can see in the editor if you open T2 in its editor.

'Optional' is then used to produce the real .NET type for code generation, which can be int? in this case if your target platform supports that. We don't store nullability with the Type, it's a separate aspect of an entity field.

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 23-Dec-2015 15:21:01   

Apologies made a mistake in the schema, T.B should be not nullable:

CREATE TABLE [dbo].[t](
    [a] [int] IDENTITY(1,1) NOT NULL,
    [b] [int] NOT NULL CONSTRAINT [DF_t_b]  DEFAULT ((1)),
 CONSTRAINT [PK_t] PRIMARY KEY CLUSTERED 
(
    [a] ASC
)
) ON [PRIMARY]

Ok, I think I understand. However looking at this from a model point of view in entity T we have 2 fields, A the identifier, and B. In entity T2 we have just the identifier and a relation to T. We want T2 generated with the field B from T so when the code for T2 is generated we get fields on T2 for the identifier field pk, the foreign key linking field fk (which from a model point of view is field A in T) and the related field B. In the code for T2 the fk (entity T's field A) is nullable and B is not nullable. I understand why based on your reply, as B maps to entity T.B which is not nullable, but it seems a bit odd. Would it be reasonable to ask in a future release that we have some checkbox on the relation which allows us to say "This relation is optional so mark all mapped related fields as optional regardless of their definition in the defining entity" ?

Maybe the reason why am I here will help my case. I have a grid where the user can create T2 entities by adding rows into the grid. This happens to be in a Telerik grid using the Silverlight controls and RIA to generate the client side entities. Mapped field B is not in the grid, reasonably as its not part of entity T2. However the client side code tracks what fields are mandatory and what are populated and before it attempts to add a new entity to the backing list, it checks that the mandatory fields are populated. It's not aware the field B is a mapped field, it just sees it as an int that has not been set and the row/entity then fails validation.

Thanks

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 23-Dec-2015 21:32:15   

IMHO the validation code should check on entityFields not on class properties.

yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 23-Dec-2015 22:53:36   

That's a fair comment. How about these two lines of code

// load T2 with a prefetch of T and assume that the T2.Fk == null

int i = T2.B; // this sets i to 0


int i = T2.T.B; // fails as T is null, so you get a NullReferenceException

Both logically retrieve the same value from the model. I'll close the thread so no need to reply, just something to be aware of I guess.

THanks