Collection with custom factory not creating custom entities

Posts   
 
    
siegemos
User
Posts: 47
Joined: 25-Jun-2007
# Posted on: 11-Nov-2011 13:47:21   

Hi All,

Using 2.6 (sorry rage ). I have created a custom entity factory with the intention of creating an entity collection of sub-type, like this:

FormInstanceCollection formInstances = new FormInstanceCollection(new ExtendedFormInstanceFactory());

However, when I try and access one of the items in the collection, it's type is still of the super-type ''FormInstanceEntity", so I get a cast exception. I can't think what I might be missing...

ExtendedFormInstanceEntity DOES inherit from FormInstanceEntity

Here's some code:

Custom Factory:

    [Serializable]
    public class ExtendedFormInstanceFactory : EntityFactoryBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExtendedFormInstanceFactory"/> class.
        /// </summary>
        public ExtendedFormInstanceFactory()
            : base("FormInstanceEntity", EntityType.FormInstanceEntity)
        {
        }

        /// <summary>
        /// Creates this instance.
        /// </summary>
        /// <returns></returns>
        public override SD.LLBLGen.Pro.ORMSupportClasses.IEntity Create()
        {
            IEntity extended = new ExtendedFormInstanceEntity();
            return extended;
        }



        /// <summary>
        /// Creates the specified fields.
        /// </summary>
        /// <param name="fields">The fields.</param>
        /// <returns></returns>
        public override IEntity Create(IEntityFields fields)
        {
            IEntity extended = new ExtendedFormInstanceEntity();
            extended.Fields = fields;
            return extended;
        }
    }

Fetching the collection:

     PredicateExpression filter = new PredicateExpression();
            filter.Add(FormInstanceFields.ApplicationId == appId);
            filter.AddWithAnd(FormInstanceFields.PageId == pageId);
            filter.AddWithAnd(FormInstanceFields.Locale == locale);
            filter.AddWithAnd(FormInstanceFields.RecordTypeId == WorkflowRecordType.Master);

            FormInstanceCollection formInstances = new FormInstanceCollection(new ExtendedFormInstanceFactory());
            formInstances.GetMulti(filter);

            if (formInstances.Count > 0)
                return (ExtendedFormInstanceEntity)formInstances[0]; //<-- Cast exception occurs here!

            return new ExtendedFormInstanceEntity();

The only other thing I can think of is that the "FormInstanceEntity" is part of a TargetPerEntity inheritance hieracrchy, should that make any difference?

Thanks, CM.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 11-Nov-2011 21:02:25   
  • Please post the full exception message and stack trace.
  • Describe your inheritance hierarchy
  • Is there any reason you want to inherit this class?

As a matter of fact, you can use the SelfServicing two-classes preset to generated code, which actually does this: generate the entity class and one inherited entity from this where you put your extra code. Also you can take a look a the TwoClasse's generated code to see what methods you have to override (as I think it's something with the creation of fields).

You also could use just partial classes. This is not inheritance but you can add your own code to your own files. But that depends on what are you trying to do.

David Elizondo | LLBLGen Support Team
siegemos
User
Posts: 47
Joined: 25-Jun-2007
# Posted on: 14-Nov-2011 10:50:50   

I've managed to track down the issue with this and found a workaround (sort of). The problem is definitely due to the TargetPerEntity inheritance. It seems when TargetPerEntity is being used, the LLBLGen DaoBase (ExecuteMultiRowRetrievalQuery) ignores the passed-in factory and uses the generated factory for the collection. There does not seem to be a way to stop it doing so. Unfortunately I do want to use DB inheritance here mainly because it's the logical design choice for the situation and I want to stick to it.

I do also have to extend the generated entity as I want it to implement an interface (in an external assembly that the generated DAL does not have access to, but my BLL code does).

I think partial classes would cause more problems than it's worth as my team has got into the habit of deleting all of the generated code before each regeneration to avoid the problems you often get when you don't (entity type conflicts etc...). Probably not the best habit but it would be a hard one to break and I know I'd spend the first few weeks having my custom code deleted.

I hadn't come across TwoClasses preset before but I suspect this will leave me with the same problem as partial classes and also, I still won't be able to implement the external interface.

The workaround is to create a new class in my business logic project that implements the interface I need and has a 'BaseEntity' property (pointing to the generated entity). Not perfect as it's completely different all the other 'extended' entities, but it will do for now.

Thanks, CM.