ArugmentOutOfRangeException updating entity

Posts   
 
    
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 15-Mar-2007 07:11:24   

Using LLBLGen 2.0.7.226, SelfServicing.

I have used CreateFields() to add some fields to my Entity. It all works fine until I make changes to that entity and try to Save() those changes back out.

Error:

Exception Details: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

Source Error:

Line 1068: { Line 1069: SomeEntityDAO dao = (SomeEntityDAO)CreateDAOInstance(); Line 1070: return dao.UpdateExisting(base.Fields, base.Transaction); Line 1071: } Line 1072:

Stack Trace:

[ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index] System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) +62 System.ThrowHelper.ThrowArgumentOutOfRangeException() +12 System.Collections.Generic.List1.get_Item(Int32 index) +2633204 SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateUpdateDQ(IEntityFieldCore[] fields, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, List1 pkFilters) +607 SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateUpdateDQ(IEntityFields fields, IDbConnection connectionToUse, List1 pkFilters) +66 SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.UpdateExisting(IEntityFields fields, ITransaction containingTransaction) +611 NameSpace.DAL.EntityClasses.SomeEntityEntityBase.UpdateEntity() in DAL\EntityBaseClasses\SomeEntityEntityBase.cs:1070 NameSpace.DAL.EntityClasses.SomeEntityEntity.UpdateEntity() in DAL\EntityClasses\SomeEntityEntity2.cs:75 SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.CallUpdateEntity() +27 SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.PersistQueue(List1 queueToPersist, Boolean insertActions, ITransaction transactionToUse) +820 SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.Save(IPredicate updateRestriction, Boolean recurse) +729 NameSpace.DAL.EntityClasses.SomeParentEntityBase.Save(IPredicate updateRestriction, Boolean recurse) in DAL\EntityBaseClasses\SomeParentEntityBase.cs:201 SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.Save(Boolean recurse) +141

Here is the code I have added to the class:

protected override IEntityFields CreateFields()
{
    IEntityFields toReturn = base.CreateFields();
    toReturn.Expand(1);
    IEntityField IsPolicyValid = new EntityField("IsPolicyValid", SqlFunctionFactory.IsPolicyValid(SomeEntityFields.SomeEntityId));
    toReturn.DefineField(IsPolicyValid, (int)SomeEntityFieldIndexExt.IsPolicyValid);
    return toReturn;
}


public enum SomeEntityFieldIndexExt : int
{
    IsPolicyValid = SsomeEntityFieldIndex.AmountOfFields
}

public bool IsPolicyValid
{
    get
    {
        return Convert.ToBoolean(this.Fields[(int)SomeEntityFieldIndexExt.IsPolicyValid].CurrentValue);
    }
}

This entity is in a hierarchy - target per entity - if that matters.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Mar-2007 08:41:29   

I have used CreateFields() to add some fields to my Entity. It all works fine until I make changes to that entity and try to Save() those changes back out.

Do these fields exist in the database? If the answer is yes, then it's better to use the designer to add them to the Entity. If the answer is no, then I think you may need to have custom properties rather than custom fields.

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 15-Mar-2007 08:47:13   

Do these fields exist in the database? If the answer is yes, then it's better to use the designer to add them to the Entity. If the answer is no, then I think you may need to have custom properties rather than custom fields.

The answer is Yes and No. No it does not exist as a field and Yes it does exist in the database. In this case it is a custom SQL function calls (see the example code above). It might have been 'NumberOfOrders' like is used in this example here: http://weblogs.asp.net/fbouma/archive/2006/06/09/LLBLGen-Pro-v2.0-with-ASP.NET-2.0.aspx where the same basic thing is done. It is retrieving a value from the database in the SQL SELECT statement and putting it as a field in the entity.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Mar-2007 09:00:17   

So you have followed the example in that blog post and created a class to extended the EntityFactory class and add overrided the CreateFields, right?

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 15-Mar-2007 17:07:24   

So you have followed the example in that blog post and created a class to extended the EntityFactory class and add overrided the CreateFields, right?

I am using self servicing (as indicated above), so NO, I have not followed that example with the Factory class, etc.

I have added the code (as indicated above) to the class.

..........frustrated here............seems like this thread is going in circles. Can someone try the above code to see the crash in the support libraries or correct the code?? disappointed

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 16-Mar-2007 04:35:42   

Why don't you define the field with toReturn.DefineField(IsPolicyValid, toReturn.Count - 1); in CreateFields?

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 16-Mar-2007 04:37:26   

Why don't you define the field with toReturn.DefineField(IsPolicyValid, toReturn.Count - 1); in CreateFields?

I could, not very maintenance friendly. I have tried that just to be sure and that has nothing to do with the problem.

Maybe Otis will look at this when he returns...

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 16-Mar-2007 05:17:11   

I thought it may have been causing the out of range. Just a quick question are you trying to use this field to set a value to call a function or just to retrieve a value from a function.

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 16-Mar-2007 05:20:15   

I thought it may have been causing the out of range. Just a quick question are you trying to use this field to set a value to call a function or just to retrieve a value from a function.

It just retrieves a value. The field is marked readonly - so I dont even know how you would use it otherwise.

I guess Otis will have to look at it when he returns. Thanks for your help.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 16-Mar-2007 05:40:53   

public bool IsPolicyValid
{
    get
    {
        return Convert.ToBoolean(this.Fields[(int)SomeEntityFieldIndexExt.IsPolicyValid].CurrentValue);
    }
}

So it is. However just to humor me and annoy you a bit simple_smile can you try this out.


protected override IEntityFields CreateFields()
{
    IEntityFields toReturn = base.CreateFields();
    toReturn.Expand(1);
    IEntityField IsPolicyValid = new EntityField("IsPolicyValid", SqlFunctionFactory.IsPolicyValid(SomeEntityFields.SomeEntityId));
    toReturn.DefineField(IsPolicyValid, toReturn.Count-1);
    return toReturn;
}

public bool IsPolicyValid
{
    get
    {
        return Convert.ToBoolean(this.Fields[this.Fields.Count - 1].CurrentValue);
    }
}

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 16-Mar-2007 06:04:14   

Actuallly, two messages ago I indicated I did try it this way.

Believe me, when I got that error, first thing I did was do it that way, just to make sure! simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 17-Mar-2007 13:56:24   

It crashes because there's no persistence info for the field specified. This is null in your field. The fields are used for INSERTS and UPDATES as well. So if the field has NO mapped DB field, don't add it to the Fields collection, add a normal property.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 17-Mar-2007 19:43:08   

I did basically what was shown here.

http://weblogs.asp.net/fbouma/archive/2006/06/09/LLBLGen-Pro-v2.0-with-ASP.NET- 2.0.aspx

I want to add these to the SQL that gets generated so I get all these in one call to the database. Right now I have about 5 functions that return a value for various things. Doing what you suggest results in 5 extra calls to the database, where I would like to get them in the same call.

The above demo shows this exact thing - adding a count(*) query result as a field, so that it is brought down with the regular entity. Can I not add these expressions to the query?

(Also, since the field is marked as read-only - why would it even care or be looking for persistance info?)

Like I said, it works GREAT until you try to save/update....really need this functionality.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 17-Mar-2007 21:07:44   

If I say the reason is that there's no persistence info, that's the reason. I can't make it more joyfull than that. THe way I did it in that example is for FETCHING, and I also add it in a factory, not in the entity itself.

What you're doing is something completely different. I'm looking at the persistence info for readonly fields as identity fields are also readonly, still they're taken care of. Also readonly fields have persistence info.

Frans Bouma | Lead developer LLBLGen Pro