T4 Templates : Reading resulting columns of a stored procedure table - templates

I am learning T4 templates right now, and all examples I got on internet is about using the tables for code generation. I want to use stored procedure result columns to generate automated UI, is it possible? OR I have to create view for same query? in that case, how to read from view?
Thanks in advance.

I got the solution and here is how you can generate a rad grid directly from the sp name
<#
'requires: <## assembly name="System.Data" #>
dim Server as new Server(".\sqlexpress")
dim database as new Database(server, "xxxx")
dim strSpName as String= "sp_xxxx"
Dim dt as System.Data.DataTable= database.ExecuteWithResults("exec sp_GetEquipment").Tables(0)
dim ctlName as String = "grdEqp"
#>
<telerik:RadGrid ID="grd" runat="server" Skin="Web20" AutoGenerateColumns="false">
<MasterTableView>
<Columns>
<#
For Each column As System.Data.DataColumn In dt.Columns
#><telerik:GridBoundColumn DataField="<#=column.ColumnName #>" HeaderText="<#=column.ColumnName #>"/>
<#Next#>
</Columns>
</MasterTableView>
</telerik:RadGrid>

If you don't actually want to execute the stored procedure as various stored procedures have a number of different parameters passed then you could use the sp_describe_first_result_set system stored procedure to return the columns of the result set assuming there is just one.
/// <summary>
/// Returns table for which stored procedures need to be generated.
/// </summary>
string TableName = "usp_getNominalCode";
string SchemaName = "Financial";
DataTable DataTable
{
get
{
if (_table == null)
{
Server server = new Server(new ServerConnection(new SqlConnection(this.ConnectionString)));
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(this.ConnectionString);
Database database = new Database(server, connectionStringBuilder.InitialCatalog);
DataSet storedProcedureColumns = database.ExecuteWithResults("sp_describe_first_result_set #tsql= " + "'[" + SchemaName + "]" + ".[" + TableName + "]'");
_table = storedProcedureColumns.Tables[0];
}
return _table;
}
}
DataTable _table;
You can then query this table for it's structure like the other answer but it'll be a little more generic

Related

How to get the results of a stored procedure when using cfscript new StoredProc()

First time trying to use a stored procedure via cfscript and I can't figure out how to get the results. With a regular query I do something like this to get my result set:
queryResult = queryResult.execute().getResult();
With the stored procedure my code is:
queryResult = new storedProc( procedure = 'stpQueryMyResultSet', datasource = 'mydsn' );
queryResult = queryResult.execute();
writeDump(queryResult);
That returns 3 structs - prefix, procResultSets and procOutVariables, but I can't seem to figure out how to get my query results.
Thanks to #Ageax for pointing me to that page. Here's how I got it working (I also added in a param for max rows to return):
queryResult = new storedProc( procedure = 'stpQueryMyResultSet', datasource = 'mydsn' );
queryResult.addParam( type = 'in', cfsqltype = 'cf_sql_integer', value = '10');
queryResult.addProcResult( name = 'result' );
qResult = queryResult.execute().getProcResultSets().result;
writeDump(qResult);

getting result metadata from coldfusion newQuery() in cfscript

Documentation on CFscript is a bit sparse in the docs, and searching for a cfscript specific answer gets lost in CF tag answers. So here's my question:
How do I get the result metadata from a query that was performed using script? Using tags I can add result="myNamedResultVar" to my cfquery. I can then refer to the query name for data, or myNamedResultVar for some metadata. However, now I'm trying to write everything in script, so my component is script based, top-to-bottom. What I'm ultimately after is the last inserted Id from a MySQL insert. That ID exists in the result metadata.
myNamedResultVar.getPrefix().generatedkey
Here's my query code:
public any function insertUser( required string name, required string email, required string pass ) {
// insert user
var sql = '';
var tmp = '';
var q = new query();
q.setDatasource( application.dsn );
q.addParam(
name='name'
,value='#trim( arguments.name )#'
,cfsqltype='CF_SQL_VARCHAR'
);
q.addParam(
name='email'
,value='#trim( arguments.email )#'
,cfsqltype='CF_SQL_VARCHAR'
);
q.addParam(
name='pass'
,value='#hashMyString( arguments.pass )#'
,cfsqltype='CF_SQL_VARCHAR'
);
sql = 'INSERT INTO
users
(
name
,email
,pass
,joined
,lastaccess
)
VALUES
(
:name
,:email
,:pass
,CURRENT_TIMESTAMP
,CURRENT_TIMESTAMP
);
';
tmp = q.execute( sql=sql );
q.clearParams();
}
How do I specify the result data? I've tried something like this:
...
tmp = q.execute( sql=sql );
var r = tmp.getResult();
r = r.getPrefix().generatedkey;
q.clearParams();
return r;
However, on an insert the getResult() returns a NULL as best I can tell. So the r.getPrefix().generatedkey does NOT work after an insert. I get r is undefined
You are getting the result property of the query first and then from that you are trying to get the prefix property in result. But this is not the case. You can directly get the prefix property and then the generated key like this:
tmp.getPrefix().generatedkey;
For reference you can check this blog entry: Getting the Generated Key From A Query in ColdFusion (Including Script Based Queries)
after some futzing... THIS seems to work
... tmp = q.execute( sql=sql );
var r = tmp.getPrefix( q ).generatedkey;
q.clearParams();
return r;

EF4: Get the linked column names from NavigationProperty of an EDMX

I am generating POCOs (lets say they are subclasses of MyEntityObject) by using a T4 template from an EDMX file.
I have 3 entities, e.g.:
MyTable1 (PrimaryKey: MyTable1ID)
MyTable2 (PrimaryKey: MyTable2ID)
MyTable3 (PrimaryKey: MyTable3ID)
These entities have the following relations:
MyTable1.MyTable1ID <=>
MyTable2.MyTable1ID (MyTable1ID is the
foreign key to MyTable1)
MyTable2.MyTable2ID <=>
MyTable3.MyTable2ID (MyTable2ID is the
foreign key to MyTable2)
Or in another view:
MyTable1 <= MyTable2 <= MyTable3
I want to extract all foreign key relations
NavigationProperty[] foreignKeys = entity.NavigationProperties.Where(np => np.DeclaringType == entity && ((AssociationType)np.RelationshipType).IsForeignKey).ToArray();
forewach (NavigationProperty foreignKey in foreignKeys)
{
// generate code....
}
My Question: How can I extract the column names that are linked between two entities?
Something like this:
void GetLinkedColumns(MyEntityObject table1, MyEntityObject table2, out string fkColumnTable1, out string fkColumnTable2)
{
// do the job
}
In the example
string myTable1Column;
string myTable2Column;
GetLinkedColumns(myTable1, myTable2, out myTable1Column, out myTable2Column);
the result should be
myTable1Column = "MyTable1ID";
myTable2Column = "MyTable2ID";
The first answer works if your foreign key columns are exposed as properties in your conceptual model. Also, the GetSourceSchemaTypes() method is only available in some of the text templates included with EF, so it is helpful to know what this method does.
If you want to always know the column names, you will need to load the AssociationType from the storage model as follows:
// Obtain a reference to the navigation property you are interested in
var navProp = GetNavigationProperty();
// Load the metadata workspace
MetadataWorkspace metadataWorkspace = null;
bool allMetadataLoaded =loader.TryLoadAllMetadata(inputFile, out metadataWorkspace);
// Get the association type from the storage model
var association = metadataWorkspace
.GetItems<AssociationType>(DataSpace.SSpace)
.Single(a => a.Name == navProp.RelationshipType.Name)
// Then look at the referential constraints
var toColumns = String.Join(",",
association.ReferentialConstraints.SelectMany(rc => rc.ToProperties));
var fromColumns = String.Join(",",
association.ReferentialConstraints.SelectMany(rc => rc.FromProperties));
In this case, loader is a MetadataLoader defined in EF.Utility.CS.ttinclude and inputFile is a standard string variable specifying the name of the .edmx file. These should already be declared in your text template.
Not sure exactly whether you want to generate code using the columns or not, but this may partly help to answer your question (How can I extract the column names that are linked between two entities?) ...
NavigationProperty[] foreignKeys = entity.NavigationProperties
.Where(np => np.DeclaringType == entity &&
((AssociationType)np.RelationshipType).IsForeignKey).ToArray();
foreach (NavigationProperty foreignKey in foreignKeys)
{
foreach(var rc in GetSourceSchemaTypes<AssociationType>()
.Single(x => x.Name == foreignKey.RelationshipType.Name)
.ReferentialConstraints)
{
foreach(var tp in rc.ToProperties)
WriteLine(tp.Name);
foreach(var fp in rc.FromProperties)
WriteLine(fp.Name);
}
}
This code works fine on my Visual Studio 2012
<## template language="C#" debug="true" hostspecific="true"#>
<## include file="EF.Utility.CS.ttinclude"#>
<#
string inputFile = #"DomainModel.edmx";
MetadataLoader loader = new MetadataLoader(this);
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
foreach (NavigationProperty navProperty in entity.NavigationProperties)
{
AssociationType association = ItemCollection.GetItems<AssociationType>().Single(a => a.Name == navProperty.RelationshipType.Name);
string fromEntity = association.ReferentialConstraints[0].FromRole.Name;
string fromEntityField = association.ReferentialConstraints[0].FromProperties[0].Name;
string toEntity = association.ReferentialConstraints[0].ToRole.Name;
string toEntityField = association.ReferentialConstraints[0].ToProperties[0].Name;
}
}
#>

Using Conversion Studio by To-Increase to import Notes into Microsoft Dynamics AX 2009

Currently, I'm using Conversion Studio to bring in a CSV file and store the contents in an AX table. This part is working. I have a block defined and the fields are correctly mapped.
The CSV file contains several comments columns, such as Comments-1, Comments-2, etc. There are a fixed number of these. The public comments are labeled as Comments-1...5, and the private comments are labeled as Private-Comment-1...5.
The desired result would be to bring the data into the AX table (as is currently working) and either concatenate the comment fields or store them as separate comments into the DocuRef table as internal or external notes.
Would it not require just setting up a new block in the Conversion Studio project that I already have setup? Can you point me to a resource that maybe shows a similar procedure or how to do this?
Thanks in advance!
After chasing the rabbit down the deepest of rabbit holes, I discovered that the easiest way to do this is like so:
Override the onEntityCommit method of your Document Handler (that extends AppDataDocumentHandler), like so:
AppEntityAction onEntityCommit(AppDocumentBlock documentBlock, AppBlock fromBlock, AppEntity toEntity)
{
AppEntityAction ret;
int64 recId; // Should point to the record currently being imported into CMCTRS
;
ret = super(documentBlock, fromBlock, toEntity);
recId = toEntity.getRecord().recId;
// Do whatever you need to do with the recId now
return ret;
}
Here is my method to insert the notes, in case you need that too:
private static boolean insertNote(RefTableId _tableId, int64 _docuRefId, str _note, str _name, boolean _isPublic)
{
DocuRef docuRef;
boolean insertResult = false;
;
if (_docuRefId)
{
try
{
docuRef.clear();
ttsbegin;
docuRef.RefCompanyId = curext();
docuRef.RefTableId = _tableId;
docuRef.RefRecId = _docuRefId;
docuRef.TypeId = 'Note';
docuRef.Name = _name;
docuRef.Notes = _note;
docuRef.Restriction = (_isPublic) ? DocuRestriction::External : DocuRestriction::Internal;
docuRef.insert();
ttscommit;
insertResult = true;
}
catch
{
ttsabort;
error("Could not insert " + ((_isPublic) ? "public" : "private") + " comment:\n\n\t\"" + _note + "\"");
}
}
return insertResult;
}

Entity 4.0 Casting Value As DateTime

LINQ to Entity Framework 4.0. SQL Server.
I'm trying to return a list of objects and one of the columns in the database is varchar(255) and contains dates. I'm trying to cast the value to datetime, but I haven't found the solution to that yet.
Example:
List<MyObject> objects = (from c in context.my_table
where c.field_id == 10
select new MyObject()
{
MyDate = c.value // This is varchar, want it to be datetime
}).ToList();
Is this not possible?
Update. This is LINQ to Entity. When trying to convert to DateTime I get:
LINQ to Entities does not recognize the method 'System.DateTime ToDateTime(System.String)' method, and this method cannot be translated into a store expression.
The answer is it's not currently possible with Entity Framework. With LINQ itself it is, just not supported with Entity Framework.
You want DateTime.Parse(c.value) which will take a string containing a date and create a DateTime object out of it.
you can do like this
Date=DateTime.Parse(text)
read, And the best bet would be using your result and then Converting to date time. Like below,
static void Main(string[] args)
{
Console.WriteLine(getme());
Console.ReadLine();
}
private static DateTime getme()
{
List<string> ss = new List<string>();
ss.Add("11/11/2010");
var r = from l in ss
select new { date = Convert.ToDateTime(l) };
return r.FirstOrDefault().date;
}