Retrieving n:1 entity returns new entity every time

Posts   
 
    
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 01-Sep-2006 16:04:09   

If you have n:1 relationship and do this:

MyNEntity nEntity = new MyNEntity();

//now, everytime you reference My1Entity, it will create a NEW My1Entity object..
nEntity.My1Entity.SomeProperty=true;
nEntity.My1Entity.SomeOtherProperty=1;

//inspect nEntity.My1Entity.SomeProperty and SomeOtherProperty, they have not been changed....

The only way to make it work is to put the My1Entity in a local variable (or create your own new one), make all the changes and then assign it back.

any help?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 01-Sep-2006 17:05:51   

WayneBrantley wrote:

If you have n:1 relationship and do this:

MyNEntity nEntity = new MyNEntity();

//now, everytime you reference My1Entity, it will create a NEW My1Entity object..
nEntity.My1Entity.SomeProperty=true;
nEntity.My1Entity.SomeOtherProperty=1;

//inspect nEntity.My1Entity.SomeProperty and SomeOtherProperty, they have not been changed....

The only way to make it work is to put the My1Entity in a local variable (or create your own new one), make all the changes and then assign it back.

any help?


nEntity.My1Entity = new My1Entity();
nEntity.My1Entity.SomeProperty=true;
nEntity.My1Entity.SomeOtherProperty=1;

It does make sense: you set the entity to a legit entity object and then set the values.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 01-Sep-2006 22:51:04   

Well, I understand, but shouldn't 'alreadybeenfetched' set to true once the entity has been requested and a 'new' one returned?

Where I ran across this is I had a function like:

void LoadValues(MyEntityN entityN)
{
    MyEntity1 entity1 = entityN.MyEntity1;
    entity1.SomeProperty=1;
    entity2.SomeProperty1="Test";
    .....
}

I would call this code with a MyEntityN object that may or may not have an associated MyEntity1 object.

What happens is, this code works if the MyEntity1 object exists or has been assigned already. If it does not, then the code does not work. The workaround is to write all code modifying subentities to be this:

void LoadValues(MyEntityN entityN)
{
    MyEntity1 entity1 = entityN.MyEntity1;
    entity1.SomeProperty=1;
    entity2.SomeProperty1="Test";
    .....
    entityN.MyEntity1=entity1;
}

If you say that is the way it is and has to be, fine - I will make sure all my code is written with this concept in mind - however, if this can be changed - I think it would make sense to return the same object each time it is requested - regardless if the object was 'new' and created on the fly or already existed.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 03-Sep-2006 10:12:54   

WayneBrantley wrote:

Well, I understand, but shouldn't 'alreadybeenfetched' set to true once the entity has been requested and a 'new' one returned?

No, it's not, as that would possibly increase the graph without you noticing it. It's an old debate: what should myOrder.Customer return if the Customer doesn't exist? Null or a new entity? So you have a choice: by default it's a new entity (but not wired to the graph), though you can have it return null, by setting the preference / project property: LazyLoadingWithoutResultsReturnsNew to false. It's true by default. (for backwards compatibility).

Where I ran across this is I had a function like:

void LoadValues(MyEntityN entityN)
{
    MyEntity1 entity1 = entityN.MyEntity1;
    entity1.SomeProperty=1;
    entity2.SomeProperty1="Test";
    .....
}

I would call this code with a MyEntityN object that may or may not have an associated MyEntity1 object.

What happens is, this code works if the MyEntity1 object exists or has been assigned already. If it does not, then the code does not work. The workaround is to write all code modifying subentities to be this:

void LoadValues(MyEntityN entityN)
{
    MyEntity1 entity1 = entityN.MyEntity1;
    entity1.SomeProperty=1;
    entity2.SomeProperty1="Test";
    .....
    entityN.MyEntity1=entity1;
}

If you say that is the way it is and has to be, fine - I will make sure all my code is written with this concept in mind - however, if this can be changed - I think it would make sense to return the same object each time it is requested - regardless if the object was 'new' and created on the fly or already existed.

You either receive a new entity that's not yet associated with the entity you called the property on, or you receive null if you've set the project property (and regenned the code).

The reason it returns a new entity and not null by default is to avoid nullreference exceptions in code which assumes there's always an entity. This is by design since the beginning, though you have the choice to let it return null through the project property.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 06-Sep-2006 03:01:18   

It's an old debate: what should myOrder.Customer return if the Customer doesn't exist? Null or a new entity?

Well, I don't want to get the debate started again! simple_smile

Related question - should this work?

MyEntity myEntity = new MyEntity();
MyEntity1 myEntity1 = new MyEntity1();
myEntity.MyEntity1 = myEntity1;
myEntity1.SomeProperty=1;

And then reference it like this:

//is this supposed to be 1?
myEntity1.MyEntity.SomeProperty
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 06-Sep-2006 07:39:03   

And then reference it like this: Code: //is this supposed to be 1? myEntity1.MyEntity.SomeProperty

Do you mean : myEntity.MyEntity1.SomeProperty ??

If yes, then I think it is supposed to be 1