Can't remove reference

Posts   
 
    
ww
User
Posts: 83
Joined: 01-Oct-2004
# Posted on: 08-Oct-2004 16:34:03   

I have two classes, EntityA and EntityB, that use GUIDs as their primary keys.

EntityA has a reference to an EntityB. Once that reference is there, I can't seem to get rid of it.


dim A as new EntityA

   'retrieve an existing A, which already has a reference to an EntityB
   A.FetchUsingPK(...)
   'now get rid of the B:
   A.MyEntityB=Nothing
   A.Save

This doesn't get rid of the B. In the setter for property MyEntityB, the code doesn't do anything if _myEntityB is already Nothing. In this case it is, because _myEntityB was never fetched.

So I changed my code with this workaround:


dim A as new EntityA
dim B as EntityB

   'retrieve an existing A, which already has a reference to an EntityB
   A.FetchUsingPK(...)

   'force retrieval of MyEntityB
   B=A.MyEntityB   

   'now get rid of the B:
   A.MyEntityB=Nothing
   A.Save

Now when I set MyEntityB to nothing, the object reference properly gets set to Nothing, but the GUID holding the identity still has a value, and that gets written back to the database when I do the save.

Am I missing something?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 08-Oct-2004 17:13:16   

ww wrote:

I have two classes, EntityA and EntityB, that use GUIDs as their primary keys.

EntityA has a reference to an EntityB. Once that reference is there, I can't seem to get rid of it.


dim A as new EntityA

   'retrieve an existing A, which already has a reference to an EntityB
   A.FetchUsingPK(...)
   'now get rid of the B:
   A.MyEntityB=Nothing
   A.Save

This doesn't get rid of the B. In the setter for property MyEntityB, the code doesn't do anything if _myEntityB is already Nothing. In this case it is, because _myEntityB was never fetched.

I'm not sure what you want to do. Do you want to delete B? Because the code you've pasted above doesn't fetch B so it doesn't need to set some reference, it doesn't do that.

What I think you want to do is to set the FK field in A to NULL before save. So instead of A.MyEntityB = Nothing do: A.SetNewFieldValue(CInt(AFieldIndex.MyEntityBId), Nothing) and then save.

Frans Bouma | Lead developer LLBLGen Pro
ww
User
Posts: 83
Joined: 01-Oct-2004
# Posted on: 08-Oct-2004 18:17:09   

Otis wrote:

I'm not sure what you want to do. Do you want to delete B? Because the code you've pasted above doesn't fetch B so it doesn't need to set some reference, it doesn't do that.

What I think you want to do is to set the FK field in A to NULL before save. So instead of A.MyEntityB = Nothing do: A.SetNewFieldValue(CInt(AFieldIndex.MyEntityBId), Nothing) and then save.

Yes, I want the FK field in A to be set to NULL. Shouldn't A.MyEntityB=Nothing do that? I'm pretty sure it did in the previous version of the library I was using.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 08-Oct-2004 19:03:07   

that was never the case, what's the case since 1.0.2004.1 of the runtimes is that if you change the FK field, the reference will be set to null / Nothing.

so if I do this: OrderEntity o = new OrderEntity(10254); CustomerEntity c = o.Customer; o.CustomerId="";

this will then make o.Customer be null

The FK field is not set to null/nothing because perhaps you don't want to have the object around because you're sending it across the wire in a remoting scenario for example, i.e.: it can be ambiguistic what the meaning is simple_smile

Working with NULL's is cumbersome though... disappointed I wished we had already nullable types.

Frans Bouma | Lead developer LLBLGen Pro
ww
User
Posts: 83
Joined: 01-Oct-2004
# Posted on: 08-Oct-2004 23:01:36   

Otis wrote:

OrderEntity o = new OrderEntity(10254); CustomerEntity c = o.Customer; o.CustomerId="";

this will then make o.Customer be null

In my case, CustomerID (or the equivalent) is a GUID, so I can't set it to "". If I set it to Guid.Empty, that doesn't work because the code tries to insert a GUID value that's all 0s.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 08-Oct-2004 23:34:51   

True, that's why you need the somewhat cumbersome method of SetNewFieldValue(). It was the only way to let fields be settable to NULL in a less awkward way...

Frans Bouma | Lead developer LLBLGen Pro
ww
User
Posts: 83
Joined: 01-Oct-2004
# Posted on: 12-Oct-2004 16:41:06   

Thanks for the info.

ww
User
Posts: 83
Joined: 01-Oct-2004
# Posted on: 12-Oct-2004 17:27:44   

OK, one more question on this. I want to add methods to my entities that will "nullify" entity references. So NullifyCustomer would set the customer and the CustomerID to Nothing.

I'd like to add this to the entityBase template so the code gets generated for all my classes. In the template it looks like this:


        public sub Nullify<[MappedFieldNameRelation]>()
            <[MappedFieldNameRelation]>=Nothing
            MyBase.SetNewFieldValue(CType(<[CurrentEntityName]>FieldIndex.XXX, Integer), Nothing)
        end sub 


Is there a token I can use for "XXX" (or some other construct I can use) to set the ID field to null for the entity? None of the tokens that are populated within the "Foreach RelatedEntity" loop seem to give me what I want.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 14-Oct-2004 17:20:35   

ww wrote:

OK, one more question on this. I want to add methods to my entities that will "nullify" entity references. So NullifyCustomer would set the customer and the CustomerID to Nothing.

I'd like to add this to the entityBase template so the code gets generated for all my classes.

Please use the include template functionality for this. (bind Custom_EntityBaseTemplate to a template you write in a custom (copy for example) of the VB.NET template set config file and use that config file during code generation.)

In the template it looks like this:


        public sub Nullify<[MappedFieldNameRelation]>()
            <[MappedFieldNameRelation]>=Nothing
            MyBase.SetNewFieldValue(CType(<[CurrentEntityName]>FieldIndex.XXX, Integer), Nothing)
        end sub 


Is there a token I can use for "XXX" (or some other construct I can use) to set the ID field to null for the entity? None of the tokens that are populated within the "Foreach RelatedEntity" loop seem to give me what I want.

Be aware of the fact that a relation can be based on 2 or more fields simple_smile Also, a relation can be 1:n or m:n so it is a collection, so only want to emit Nullify routines for m:1 and 1:1 relations.

Use a construct like:


<[ Foreach RelationField ]>
    MyBase.SetNewFieldValue(CInt(<[CurrentEntityName]>FieldIndex.<[RelationFieldName]>), Nothing)
<[NextForeach]>

simple_smile

You can also opt for the default value for the field though, as Nothing will give problems when the entity is later on bound to a grid or other control.

Frans Bouma | Lead developer LLBLGen Pro
ww
User
Posts: 83
Joined: 01-Oct-2004
# Posted on: 14-Oct-2004 18:17:05   

Perfect. Thanks!