I can't figure this one out. Why doesn't T4 locate the IEnumerable type? I'm using Visual Studio 2010. And I just hope someone knows why?
<## template debug="true" hostspecific="false" language="C#" #>
<## assembly name="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" #>
<## import namespace="System" #>
<## import namespace="System.Data" #>
<## import namespace="System.Data.SqlClient" #>
<## output extension=".cs" #>
public static class Tables
{
<#
var q = #"
SELECT
tbl.name 'table',
col.name 'column'
FROM
sys.tables tbl
INNER JOIN
sys.columns col ON col.object_id = tbl.object_id
";
// var source = Execute(q);
#>
}
<#+
static IEnumerable Execute(string cmdText)
{
using (var conn = new SqlConnection(#"Data Source=.\SQLEXPRESS;Initial Catalog=t4build;Integrated Security=True;"))
{
conn.Open();
var cmd = new SqlCommand(cmdText, conn);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
}
}
}
}
#>
Error 2 Compiling transformation: The type or namespace name 'IEnumerable' could not be found (are you missing a using directive or an assembly reference?) c:\Projects\T4BuildApp\T4BuildApp\TextTemplate1.tt 26 9
I would also recommend to referece #assembly name="System.Core" and #import "System.Linq" so you get more power when doing something with IEnumerable
Probably because IEnumerable is in System.Collections.
Related
For some reason i keep getting a referencing error for:
(8,6): error CS0246: The type or namespace name `MenuItem' could not be found. Are you missing an assembly reference?
(24,26): error CS0246: The type or namespace name `SerializedObject' could not be found. Are you missing an assembly reference?
Code:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class AudioSourceReplacement {
[MenuItem("FMOD Tools/Replace Audio Emitters")]
private static void ReplaceEmitters()
{
AudioSource[] audioSources = Object.FindObjectsOfType<AudioSource>();
foreach (AudioSource audioSource in audioSources)
{
if (audioSource.clip == null)
{
continue;
}
string eventName = audioSource.clip.name;
string eventPath = (audioSource.spatialBlend < 0.5f ? "event:/Ambience/2D/" : "event:/Ambience/3D/") + eventName;
FMODUnity.StudioEventEmitter emitter = audioSource.gameObject.AddComponent<FMODUnity.StudioEventEmitter>();
emitter.Event = eventPath;
var so = new SerializedObject(emitter);
so.ApplyModifiedProperties();
}
for (int i=0;i<audioSources.Length;i++)
{
GameObject.DestroyImmediate(audioSources[i]);
}
}
[MenuItem("FMOD Tools/Force All Emitters Play On Start")]
private static void EmittersPlayOnStart()
{
FMODUnity.StudioEventEmitter[] audioSources = Object.FindObjectsOfType<FMODUnity.StudioEventEmitter>();
foreach (FMODUnity.StudioEventEmitter audioSource in audioSources)
{
audioSource.PlayEvent = FMODUnity.EmitterGameEvent.ObjectStart;
}
}
}
You have to put your script inside your "Editor" folder. "Assets/Editor/AudioSourceReplacement.cs" should do the trick.
This might happen because you didn't put this script inside an 'Editor' folder. It's one of these Special Folders.
how to use EnvDTE get static class
<## template debug="false" hostspecific="true" language="C#" #>
<## assembly name="System.Core" #>
<## assembly name="EnvDTE" #>
<## import namespace="System.Linq" #>
<## import namespace="System.Text" #>
<## import namespace="System.Collections.Generic" #>
<## import namespace="EnvDTE" #>
<## output extension=".txt" #>
<#
IServiceProvider hostServiceProvider = Host as IServiceProvider;
EnvDTE.DTE dte = hostServiceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
EnvDTE.ProjectItem containingProjectItem = dte.Solution.FindProjectItem(Host.TemplateFile);
Project project = containingProjectItem.ContainingProject;
var codes= project.CodeModel.CodeElements;
foreach (CodeElement code in codes) {
if (code.Name=="MS") continue;
if (code.Name=="System") continue;
if (code.Name=="Microsoft") continue;
if (code.Name.StartsWith("EnvDTE")) continue;
try
{
foreach (CodeElement item in ((CodeNamespace)code).Members) {
if (item.Kind== vsCMElement.vsCMElementClass) {
CodeClass cc = (CodeClass)item;
#>
<#=cc.Name #>
<#
}
}
} catch {}
} #>
this is T4 codes;
It can output the class name,
But it can not determine whether the class is static.
I want to output static class name.
Add references:
<## assembly name="EnvDTE80" #>
<## import namespace="EnvDTE80" #>
Use CodeClass2 interface, that has IsShared property
I have this XML data
<Address Location="ABC">
<Add Location="XYZ1" street="street1" />
<Add Location="VZC" street="street1" />
</Address>
I want to find out the value of <add> --> street which is street1
I have tried it as below, not getting the result
var q = from res in xmlDoc.Descendants("Address")
where res.Attribute("Location").Value == "ABC"
&& res.Element("Add").Attribute("Location").Value == "VZC"
select new
{
streetadd= res.Element("Add").Attribute("street").Value,
};
Please someone suggest how to check the condition for child element in this case.
Try this:
var query = from res in xmlDoc.Descendants("Address")
where res.Attribute("Location").Value == "ABC"
from child in res.Elements("Add")
where child.Attribute("Location").Value == "VZC"
select new
{
streetadd = child.Attribute("street").Value
};
I am trying to use LINQ to replace the following code..
public List<LineItem> GetEULineItems(PurchaseOrder p)
{
List<LineItem> EULineItems = new List<LineItem>();
foreach (LineItem li in p.OrderForms[0].LineItems)
{
if (li[Constants.ProductSource] != null)
{
if (li[Constants.ProductSource].ToString().Trim() == "EU")
{
EULineItems.Add(li);
}
}
}
return EULineItems;
}
I tried this but am gettin an exception..
IQueryable<LineItem> EULineItems = p.OrderForms[0].LineItems.AsQueryable().Where(s => s.ProductSource == "EU");
Exception:
'System.Linq.IQueryable' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument of type 'System.Linq.IQueryable' could be found (are you missing a using directive or an assembly reference?)
Assuming you are in fact using a custom collection you are not looking for an IQueryable, you are looking for an IEnumerable, and that should work right out of the box:
IEnumerable<LineItem> EULineItems = p.OrderForms[0]
.LineItems
.Where(s => s.ProductSource == "EU");
(provided of course you have a using System.Linq in your code file).
I'm starting to investigate T4 for Code Generation.
I get that you have a basic template in which you can embed little chunks of c#/vb which can perform clever stuff...
<## template language="VB" debug="True" hostspecific="True" #>
<## output extension=".vb" debug="True" hostspecific="True" #>
Imports System
<#For Each Table as String in New String(0 {"Table1","Table2"}#>
Public Class <#=Table#>DA
Public Sub New
<#= WriteConstructorBody() #>
End Sub
End Class
<#Next#>
<#+
Public Function WriteConstructorBody() as String
return "' Some comment"
End function
#>
This is great.. However I would like to be able to write my main block thus...
<## template language="VB" debug="True" hostspecific="True" #>
<## output extension=".vb" debug="True" hostspecific="True" #>
Imports System
<#
For Each BaseTableName as String in New String(){"Table1","Table2"}
WriteRecDataInterface(BaseTableName)
WriteRecDataClass(BaseTableName)
WriteDAInterface(BaseTableName)
WriteDAClass(BaseTableName)
Next
#>
Then I would like to be able to have the WriteX methods exist in a Class Block but themselves be writable using code by example ie escaped Code blocks.
How can I achieve this?
You can write.....
<## template language="VB" debug="True" hostspecific="True" #>
<## output extension=".vb" debug="True" hostspecific="True" #>
Imports System
<#
For Each BaseTableName as String in New String(){"Table1","Table2"}
WriteRecDataInterface(BaseTableName)
' WriteRecDataClass(BaseTableName)
' WriteDAInterface(BaseTableName)
' WriteDAClass(BaseTableName)
Next
#>
<#+ Public Sub WriteRecDataInterface(BaseTableName as String)#>
Some Templated unescaped code might go here
<#+ For SomeLoopVar as Integer = 1 to 10 #>
Some Templated unescaped code might go here
<#+ Next #>
Some Templated unescaped code might go here
<#+ End Sub #>
'...
'...
' Other Subs left out for brevity
'...
It seems that you can mix static output with template code in Class Blocks. Here is an example with C#:
<## template language="C#" #>
<# HelloWorld(); #>
<#+
private string _field = "classy";
private void HelloWorld()
{
for(int i = 1; i <= 3; i++)
{
#>
Hello <#=_field#> World <#= i #>!
<#+
}
}
#>