Problems with CodeSmith C# Template

Problems with CodeSmith C# Template

Old forum URL: forums.lhotka.net/forums/t/6149.aspx


Rizshe posted on Wednesday, January 14, 2009

Hi,
I'm working with CSLA2.0 for sometime.
In a recent project we tried to use CodeSmith to generate C# templates and I'm having problems.
Maybe its my understanding OR my lack of knowledge, either way I need some serious help.

This is the actual code which I wrote a while back.

namespace BDD.MyImpact.Library.BO
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using BDD.MyImpact.Library.Data;

///
/// Readonlylist of a Person Publications
///
[Serializable]
public class PersonPublicationList : ReadOnlyList
{
String _user = String.Empty;
public String User
{
get
{
return this._user;
}
}

#region Factory Methods
private PersonPublicationList()
{

}

public static PersonPublicationList GetPublicationList(String user)
{
return DataPortal.Fetch(new Criteria(user));
}
#endregion

#region Criteria
[Serializable()]
private class Criteria
{
private String _user;

public String User
{
get
{
return this._user;
}
}

public Criteria(String login)
{
this._user = login;
}

}

#endregion

#region Data Access

private void DataPortal_Fetch(Criteria criteria)
{
using (SqlConnection cn = new SqlConnection(Database.MyImpactConnection))
{
cn.Open();
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "miapp.pc_get_PersonPublicationList";
cm.Parameters.AddWithValue("@user", criteria.User);
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
IsReadOnly = false;
while (dr.Read())
{
PublicationInfo info = new PublicationInfo(dr.GetInt32("pub_id"),
dr.GetString("Title").ToString(),
dr.GetInt16("Year"),
dr.GetString("web_html"),
dr.GetString("journal"));
this.Add(info);

}
IsReadOnly = true;
}
}
}

}
#endregion
}
}
---------------------------------------
I already have a child object for this class which is already in use by another parent class that is why I don't want to generate the child.

---------------------------------------------
I tried to do SplitPartial but disregard it after I find it a bit rigid in terms of modification as I regarded the generated classes not to be touched and user classes are the ones to be modifiable.
I then sort of go towards the SplitBase as I can easily override the methods but here again I'm having problems.
Here is the code the XML template above generated.

using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using BDD.MyImpact.Library.Data;

namespace BDD.MyImpact.Library.BO
{
[Serializable()]
public abstract class PersonPublicationListBase : Csla.ReadOnlyListBase
where T : PersonPublicationListBase
where C : PublicationInfoBase
{

#region Factory Methods
public static T GetPersonPublicationList()
{
return DataPortal.Fetch(new FilterCriteria());
}
#endregion //Factory Methods

#region Data Access

#region Filter Criteria
[Serializable()]
protected class FilterCriteria : Csla.CriteriaBase
{

public FilterCriteria() : base(typeof(T))
{

}
}
#endregion //Filter Criteria

#region Data Access - Fetch
[Transactional(TransactionalTypes.TransactionScope)]
private void DataPortal_Fetch(FilterCriteria criteria)
{
RaiseListChangedEvents = false;
IsReadOnly = false;

using (SqlConnection cn = new SqlConnection(Database.MyImpactConnection))
{
cn.Open();

ExecuteFetch(cn, criteria);
}//using

IsReadOnly = true;
RaiseListChangedEvents = true;
}

protected virtual void ExecuteFetch(SqlConnection cn, FilterCriteria criteria)
{
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "pc_get_PersonPublicationList";


using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
while (dr.Read())
this.Add(PublicationInfoBase.GetPublicationInfo(dr));
}
}//using
}
#endregion //Data Access - Fetch
#endregion //Data Access
}
}

------------------------------------
Now If you take a look at the code which I wrote and the code which is generated there are differences and I couldn't find a way to sort of get rid of those differences which is essential to let me work?
Any ideas?

Thanks

Rizshe replied on Friday, January 16, 2009

Isn't there anyone who explain as all I need is an explanation :)

Regards,
Rizwan

bniemyjski replied on Wednesday, January 21, 2009

Hello,

To make the changes in the generated code you would need to open up the CodeSmith Template in CodeSmith Studio or notepad and make the changes and regenerate. For the current CodeSmith CSLA templates, I would log all bugs on the CSLA CodePlex Site.

Just a heads up that we are currently creating new CSLA 3.6.x templates for CodeSmith. If you have any suggestions please let me know.

Thanks
-Blake Niemyjski

Gort replied on Thursday, February 25, 2010

Blake-

I have grabbed your templates from the nightly build and am attempting to use them.  What I am not seeing is the child properties being created for an object.  For example, I have a 'Patient' table and am creating a ReadOnlyRoot for it.  The Patient table has a couple of tables that have PatientId as their foreign key and are set up to be 1 to many with Patient.  So, a Patient can have several addresses, i.e. PatientAddress.  But, the PatientAddress property is not getting created in my PatientInfo class.  Should it?

Tks.

bniemyjski replied on Thursday, February 25, 2010

Hello,

Currently read only stereo types do not have any child properties generated. I wasn't sure if this was standard practice or not. My thoughts were that read only stereo types were usually used one deep. What are your thoughts on this?

Thanks

-Blake Niemyjski

jamie.clayton replied on Thursday, February 25, 2010

Gort,

I'm working with the nightly builds of Codesmiths CSLA.  I must admit to have only generated one readonly list at this stage and had to do some manual code changes to the generated output to make it compile.

When I get to migrating my existing Readonly CSLA objects to the new Codesmith templates I'll report any errors to http://code.google.com/p/codesmith/issues/list. Blake and Codesmith have been outstanding at template changes to fix issues identified.

From a design perspective I've only ever design parent readonly lists and readonly child items, so I can populate combo boxes or search lists.  I'm assuming your suggesting that the Codesmith templates should also generate Grandchildren + any other database relationships when you create a readonly stereotype via codesmiths templates. Is that what you are suggesting?

bniemyjski replied on Tuesday, August 03, 2010

Hello,

If you are interested in upgrading to CSLA 3.8 or CSLA 4.0. We now have a solid set of templates located here. We also have unit tests for all the collections and child's that can be downloaded here. They are a great learning resource and go great with Rocky's Videos!

Thanks

-Blake Niemyjski

Q Johnson replied on Sunday, August 29, 2010

Blake,

The 3.8 templates are great news.  In fact, they are finally motivating me to adopt CodeSmith, so I'll be getting in the next couple of days and taking a much closer look at your admirable work here.

One quick question.  I saw a blog entry you offered very recently about using the IS_GENERIC SQL Extended Proprty.  I'm like most developers and can't control all aspects of the databases with which my programs operate.  I'll be lucky to get the DBAs to let me have my own Extended Properties at all.  But I sure won't be able to name them anything like IS_GENERIC.  (They have naming conventions for other db objects I'm allowed to create and I'm pretty sure I'll have to follow them here, too).

So, finally getting to the question <g>, is it a fairly simple matter for me to alter the template(s) to trigger off an Extended Property with a name of my own choosing, rather than IS_GENERIC to accomplish the same rendering goal?

Thanks for all your work.  I look forward to diving into it

bniemyjski replied on Sunday, August 29, 2010

Hello,

It is an extended property that has nothing to do with the data or the table names. What naming convention will they follow? We will be releasing a new version of the templates very soon. Yeah this would be an easy change. I don't think it is currently configurable in configuration (which I'll make sure it is moved there Smile. But it would be a replace a line of code quick change. 

Thanks

-Blake Niemyjski

Q Johnson replied on Monday, August 30, 2010

The naming convention they use is to prefixe ANY name you want to use with "sip" (for a now-defunct program they had with their third party developers called "system integrator partners".  Then, for our own self preservation, we in the 3rd party also add our own company abbreviation to the "actual" name.  Some put theirs at the end, I like to put ours at the beginning.  Since our company name is TeamNFP, we call our sProc to get employee data sip_tnfp_getEmployee, for example.

This doesn't seem like something you should try and cater to with your new release.  But if you could make it configurable, that would be super.  Then I wouldn't even have to rely on that company respecting the Extended Properties I create when they perform the programatic updates to their databases with each version release.  They're kind enough to bring along the tables and views and sProcs that start with 'sip' when they are doing their own.  But I don't have a committment from them yet on Extended Properties.

The change of the line of code looks like fine control to me.  And couldn't I just configure it as a template Property and then change the code in the template to look for that instead of the extended property?  That might be easiest of all.  Then you don't really have to do anything.  But before I go recommending much in the way of support, I better get a good feel for the scope of those Property values in templates and projects and where that generic tooling will be useful (e.g., will it by good for use on parent objects but not children?).  If I get a strong feeling about it after studying your tutorials and the CSLA templates and sub-templates, you'll hear back from me.

Thanks for the reply,

bniemyjski replied on Monday, August 30, 2010

Hello,

I'd like to get the configuration to the point where its just driven from an app.config. I wouldn't change the templates for this as it is one place in code where this is checked and its a property in code not in the template itself.

Too be honest with you, I haven't used the Generic Property, just added it into the templates as it was a patch and I asked a few CSLA users if they would find it useful and they said yes. If you find any bugs with it, please let me know (we have an issue tracker located here).

Thanks

-Blake Niemyjski

jamie.clayton replied on Thursday, February 25, 2010

Rizshe,

I'm using the latest nightly build of Codemiths CSLA templates and have this working.

If you are using the Entities.cst and the resulting Entity.csp file in Visual Studio you need to do the following.

  1. Right click on the Entity.csp file in Visual Studio.
  2. Select Manage menu option.
  3. Goto 1.Data Source
  4. Edit the "IgnoreExpression" list.
  5. Add all the related tables you want "ignored" or skipped when generating the templates. Codesmiths templates will then not generate the properties relationships  for those tables you defined in IgnoreExpression.

I've found I create a series of entries in the Entity.csp Codesmith project file pointing to the Entity.cst template and use these options so codesmith generates my CSLA business objects to suit my requirements.  Often the Codesmith templates are too aggressive creating the relationships, especially in highly normalized databases (which isn't codesmiths templates fault, more the database relationships your working with).

daisyfreya123 replied on Monday, August 30, 2010

I'll try the code very soon and reply you with some new content.

daisyfreya123 replied on Monday, August 30, 2010

I'll will try the code provided by you and reply you soon.

Copyright (c) Marimer LLC