MarimerLLC / cslaforum

Discussion forum for CSLA .NET
https://cslanet.com
Other
31 stars 6 forks source link

Calling CreateChild in inherited models and DataPortal factories #115

Open gfgw opened 8 years ago

gfgw commented 8 years ago

We have a problem getting the CreateChild method in a DataPortal factory. In our application we have a base model class, which looks like this:

[Serializable]
public abstract class Entity<T> : BusinessBase<T> where T : Entity<T>
{
...
    public static T Create() { return DataPortal.Create<T>(); }
    public static T CreateChild() { return DataPortal.CreateChild<T>(); }
...
}

Another model inherits from Entity:

[Serializable]
[Csla.Server.ObjectFactory("MyEntityDal")]
public class MyEntity : OrderedEntity<MyEntity>
{
...
    public static new MyEntity Create() { return DataPortal.Create<MyEntity>(); }
    public static new MyEntity CreateChild() { return DataPortal.CreateChild<MyEntity>(); }
...
}

MyEntityDal looks like this:

public class MyEntityDal : Dal<MyEntity, MyEntityList>
{
...
    [RunLocal]
    public RiskControlMeasureAction Create()
    {
    ...
    }
    [RunLocal]
    public RiskControlMeasureAction CreateChild()
    {
    ...
    }
...
}

It inherits from:

public class Dal: ObjectFactory
{
...
}

When I run the following code, I expect MyEntityDal.CreateChild to be called:

var newEntity = MyEntity.CreateChild();

But it isn't. If I set a breakpoint, it isn't hit. Properties that are set in MyEntityDal.CreateChild remain unset. The same happens with (where entities is of type MyEntityList, a BusinessListBase:

    var newEntity = entities.AddNew();

The CSLA documentation says the following for the AddNew method: When the AddNew method is invoked, a virtual method named AddNewCore is invoked to do the work of creating the child object, initializing that object, and adding it to the list. … The CSLA .NET base classes provide a default implementation of AddNewCore that directly invokes the data portal’s CreateChild method to create a new child object. In other words, by default the AddNew method “just works” on .NET and Silverlight. You can override this behavior if you need to customize the process.

Why isn't DataPortal.CreateChild ending up in MyEntityDal.CreateChild?

We are using CSLA 4.5.501.

jonnybee commented 8 years ago

ObjectFactory only supports the "root" DataPortal methods.

You only use ObjectFactory on "root" objects (or objects that use the "root" dataportal for lazy loading -ie Create/Fetch) Do NOT use

Ie: Within you ObjectFactory Dal - this code must know how to create a child object when it is required to create a child as part of a "root" object need for Create/Fetch/persist. .

Ex: CreateChild does NOT require a roundtrip to the data access layer.

rockfordlhotka commented 8 years ago

Additionally, the AddNew method isn't the same as the new keyword in C#.

The AddNew method is part of the data binding interface model defined by Microsoft, and is the method called by a datagrid control when the user moves to a new row at the bottom of the datagrid.

What your code is doing is using the new keyword to create an instance of a type. That has nothing to do with data binding, and so there's nothing in your code that invokes the AddNew method.