Setting default entity value in code

Posts   
 
    
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 08-Oct-2008 14:19:07   

Hi,

I want to simulate DB defaults for an LLBLGen generated entity (Adapter) in code. I have added following code:

public partial class TemplateFieldEntity { protected override void OnInitialized() { base.OnInitialized(); if (IsNew) { IsEnabled = true; } } }

which works fine when I instantiate a single entity but fails if TemplateFieldEntity (many of those) are fetched as part of a parent entity (TemplateEntity.Fields using prefetch path). Clearly TemplateFieldEntity.IsNew == true when OnInitialized is called in the latter scenario and is false in the first one.

Please advise how to solve this problem.

Best regards, Robert Wilczynski.

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 08-Oct-2008 16:54:36   

want to simulate DB defaults

which works fine when I instantiate a single entity but fails if TemplateFieldEntity (many of those) are fetched as part of a parent entity (TemplateEntity.Fields using prefetch path).

As far as I know default values are used while inserting. But when you fetch, the database values are returned, so I can't understand why you need default values for fetched records.

Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 09-Oct-2008 09:55:08   

I don't need them but I still get them - this is the problem. When I fetch a single instance of TemplateFieldEntity it seems to work but if a collection of TemplateFieldEntity is fetched as a property of a parent entity it doesn't (I get defaults for all items in a collection TemplateEntity.Fields instead of the DB value).

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 09-Oct-2008 12:01:01   

When I fetch a single instance of TemplateFieldEntity it seems to work

Would you please explain what "work" means here?

but if a collection of TemplateFieldEntity is fetched as a property of a parent entity it doesn't (I get defaults for all items in a collection TemplateEntity.Fields instead of the DB value).

Pick an entity from the collection and check its Fields.State property, and whether the value is EntityState.Fetched or EntityState.IsNew.

Maybe no entities were fetched in the first place.

Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 09-Oct-2008 13:08:53   

This is a unit test exhibiting this behavior that should make things clearer:

    public void TemplateIsGettingSavedTest3()
    {
        // TemplateService used to fetch and save
        TemplateService service = new TemplateService();


        TemplateEntity template = new TemplateEntity();
        template.Name = DataCreator.GetUniqueString();
        template.Description = DataCreator.GetUniqueString();
        template.IsActive = true;

        TemplateFieldEntity field = new TemplateFieldEntity();
        field.Name = "test";
        field.FieldTypeName = "Date";
        field.Label = "test";
        Assert.IsTrue(field.IsEnabled); // note that this is set to true in "protected override void OnInitialized()"
        field.IsEnabled = false; // overriding default
        template.Fields.Add(field);
        service.SaveTemplate(template);
        Assert.IsFalse(template.IsNew);

        // Fetching a single entity of the field previously saved with template
        TemplateFieldEntity fetchedField = new TemplateFieldEntity(field.TemplateFieldId);
        using (DataAccessAdapter adapter = new DataAccessAdapter())
        {
            adapter.FetchEntity(fetchedField);
        }
        // Works as expected - fetchedField.IsEnabled is not set to default 'true'
        Assert.IsFalse(fetchedField.IsEnabled);

        // Fetching a field as part of parent entity
        TemplateEntity fetchedTemplate = service.GetTemplate(template.TemplateId);

        Assert.AreEqual(EntityState.Fetched, fetchedTemplate.Fields[0].Fields.State);

        // !!! Doesn't work as expected - fetchedField.IsEnabled seems to be set to default 'true'
        Assert.IsFalse(fetchedTemplate.Fields[0].IsEnabled);
    }

It fails on the last assertion which I would consider a very inconsistent behavior from LLBLGen if the following line (earlier in test):

Assert.IsFalse(fetchedField.IsEnabled);

passes the assertion.

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 09-Oct-2008 13:56:20   

I'm not sure if this would make a diffference, but would you please try to put your code in OnInitClassMembersComplete() instead of OnInitialized()?

Also which LLBLGen Pro runtime library are you using?

Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 09-Oct-2008 14:16:38   

OnInitClassMembersComplete doesn't seem to change anything - still getting the same strange behavior.

I'm using 2.6.8.606 version of LLBLGen libraries.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 09-Oct-2008 14:42:27   

Will look into it.

Though, you really have to upgrade to the latest runtime build. We have had some changes in the runtime lib which might fix the issue you run into.

Frans Bouma | Lead developer LLBLGen Pro
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 09-Oct-2008 15:01:22   

Thanks for the suggestion:

I upgraded to:

SD.LLBLGen.Pro.DQE.SqlServer.NET20 2.6.8.903 SD.LLBLGen.Pro.LinqSupportClasses.NET35 2.6.8.911 SD.LLBLGen.Pro.ORMSupportClasses.NET20 2.6.8.911

I believe those are the latest libraries.

Still doesn't work (tried OnInitClassMembersComplete too)

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 09-Oct-2008 17:42:23   

Thanks.

Btw, you have a field mapped onto a relation called 'Fields' ? That hides the entity property 'Fields'.. this should give errors / compiler warnings. Not that I think it's related, just a FYI.

Looking into your issue.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 09-Oct-2008 17:54:27   

The problem is this: (there's a solution, - with a single entity, the entity is instantiated, gets an empty EntityFields2 instance, OnInitialized is called. Then afterwards you fetch it, values are overwritten, everything is fine.

  • with collection fetches (it also goes wrong if you simply fetch a collection), the datareader is traversed, every row is fetched into an EntityFields2 instance and then passed to a new instance of the entity, through the CTor.

This means that although 'IsNew' is true (it's set to false right after that) you will overwrite fetched data.

So do: public partial class TemplateFieldEntity { protected override void OnInitialized() { base.OnInitialized(); if((this.Fields!=null) && (this.Fields.State!=EntityState.Fetched)) { IsEnabled = true; } } }

this works, because it only sets the value if the state isn't fetched which is when the entity is new.

Frans Bouma | Lead developer LLBLGen Pro
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 09-Oct-2008 18:29:30   

Thanks Frans, this solved the problem.