I have an EditableChild object that is used within multiple EditableRoot objects.
Specifically speaking I have a this structure
Request (of EditableChild), AccessRequest (of EditableRoot), ConcurrentRequest(of EditableRoot), HardwareRequest(of EditableRoot)
So, the Request editable child object has an Update function that requires a parameter object. What type of object do I pass it. I am generating this code with codesmith so right now I am generating the Request object with a parent type of object. However, this breaks the strong typing CSLA gives, does it not? I obviously don't want a different type of RequestObject as that's just silly.
Thoughts?
Thanks, Will
I agree with Andres.
In ver 1.x I created an Interface named IParent which has a single Property named Key.
Then in any BO which hits the DB and returns an Identity value I know I need to pass the Key to the child BOs so I always pass the Parent BO as IParent and extract the Key from the Interface. This is the only case I have ever come up with for passing the parent as a Parameter. In all other cases I omit it.
Note: Rocky added and IParent interface in Csla 2 - but since they are in different namespaces I should be OK. But I may have to qualify mine after I complete the upgrade.
Joe
Xal:
You hint that this design may not be a good idea? What do you mean and do you have a better approach? I am not tied to doing things this way, it just seems the most logical since I have data and rules specific to all request types (the Request object) and then I have values and rules specific to each type of request.
Would it be better to subclass the request object in this case?
Thanks, Will
I think we are on the same lines. Here is my current model.
Request - implements all rules associated with a request (requires name, description, request_date, needed_date and a few more things.
AccessRequest : Request -- implements logic specific to access request (what module, director approval)
BugFixRequest : Request -- what application has the bug, describe the bug, major/minor bug, etc.
so on and so forth. It seems like inheritance is the way to go here. I definite have "is-a" relations (AccessRequest IS A Request). I don't anticipate issues where I'll need to do things like "If parent is ParentType1 Then" as all the requests are treated separately except for cases where we will simply be listing all requests in which case we'll simply be querying the Request object and not care about the superclass.
Now another question. How do we get CodeSmith to allow inheritance? Right now is simply assumes the base class from the Csla type... Might be worth another post but I figured I'd ask it here.
Thanks
Will
I agree with the get it working part. Our data model has a table for Requests and then other tables for specific information. So we do have a Request, AccessRequest, ConcurrentRequest, etc table all keyed on the RequestID column of the Request table.
To generate right now we are pulling directly from the table based on an ORM. To go with the all in one class approach we would have to pull data from procedures I presume and that's an avenue of CodeSmith we have not yet explored. We also generate our sprocs using CodeSmith so these would then have to be tailored to allow for joins in order to generate the all-in-one objects from them.
I'm honestly not sure how inheritance plays into the sproc generation either but I don't think it imposes any issues. The standard sprocs will still function perfectly fine I think.
Also, the all unique class (without a base class) would make it difficult for me to simply display a list of ALL requests unless I still have a Request object. This is another reason I was looking to inheritance.
Will
Thanks Andrés
You've been a big help. I think I will see about the Interface which I totally agree with as well as the all-in-one objects. This may provide better performance in the long run anyway as it seems Csla would require at least two trips to the database using inheritance (one for the base and one for the derived class). This may turn out to be a better method overall.
Cheers! Will
Yeah, that is the way the CodeSmith templates currently generate. However, this poses a question for me.
Right now I have
class AccessRequest : IMyRequest
{
RequestEC _requestEC;
......
}
where the ExecuteFetch function does FetchObject then FetchChildren
So in my database I would do something like
select ar.[x],ar.,ar. from AccessRequest ar where ar.ID = 1
select r.,r.,r. from Request r inner join AccessRequest ar on as.Request_ID = r.ID where ar.ID = 1
This will return 2 resultsets to me AccessRequest object. Now, what happens if I need yet another level on this? If I have a BO that uses a member of AccessRequest. Now I have 3 resultsets coming back from my sproc and I have to keep track of what order they are in? Or is there a better way to handle this? Note: I don't currently see the need for grandchild (or deeper) objects but it is conceivable.
Also, I guess for just child objects I have to generate the code and then write the sprocs against the code. Or attempt to predict the order the child objects will get rendered in the code.
Once again, it seems quite a lot like code generation is only really useful for the most simple cases.
Will
All I gave you was x,y,z an a,b,c. How the heck did you get those specifics about my database? My boss is going to kick my databits!
So you're saying you'd return a single datarow for the object in the form of
x,y,z,a,b,c,1,2,3 and have the GetObject function just reference the columns by name and don't do a dr.NextResult to get to the child object (since in reality the object can be represented by a single row using a join? Or do you mean something else?
Will
Ok, now for the sake of code generation. Current the templates for CodeSmith do a dr.NextResult() in the FetchChildren function. So I guess now what I should do is add an attribute to my ORM that says something like "UseSameResultForChild = true/false" then change the template to output the dr.NextResult only if that flag is false.
I also see another issue with this now though and that is, what if my parent object and child object both have an ID field. I need some way to resolve the proper ID into the proper object. Any ideas?
I have similar columns all over (CreationDate, Last_Updated_By, TimeStamp)...
Will
Disregard that. I am actually told from our SQL pro here that in many cases doing multiple selects in a spproc is as fast as returning the single massive row and he thinks it would be fine to just use the existing dr.NextResult functionality built into the CSLA templates.
I think we will design along these lines for the time being.
Thanks for all the input Andres,
Will
Well, it seems that the factory model in Csla (or at least that imposed by the codesmith templates) will not allow inheritance.
Error 3 'RequestER()' is inaccessible due to its protection level
Because the constructor or RequestER is private. So, it I make it available for inheritance, I no longer have an enforced factory here
How are you guys going about this? This would put me back to encapsulation where my
AccessRequest object would simply have a member of type Request.
I can go with protected on the constructor of the Request object. This at least compiles but I'm not sure of the overall ramifications.
Thoughts? Will
Copyright (c) Marimer LLC