-
Notifications
You must be signed in to change notification settings - Fork 226
Settings.WriteInsideClassBody
Injects a block of your own C# into the body of each generated entity class.
| Type |
Func<Table, string> - return the code, or string.Empty for none |
| Default | Returns string.Empty
|
| Applies to | EF 6 and EF Core |
| Databases | All |
In Database.tt? |
Yes, with a commented-out example |
Returns text that is written verbatim inside the class, before the properties. It is a text hook, not a model hook: the generator does not parse or validate what you return.
Reach for it when the same boilerplate belongs on many entities and a partial class per entity would be worse.
INotifyPropertyChanged is the canonical case - you need the event and the raiser on every class, and writing
one partial file per table is not a serious option.
Settings.WriteInsideClassBody = delegate(Table t)
{
if (t.NameHumanCase != "Category")
return string.Empty;
return
" public override string ToString()" + Environment.NewLine +
" {" + Environment.NewLine +
" return CategoryName;" + Environment.NewLine +
" }" + Environment.NewLine;
}; // Category
public class Category
{
public override string ToString()
{
return CategoryName;
}
public int CategoryId { get; set; } // CategoryId (Primary key)
public string CategoryName { get; set; } // CategoryName (length: 50)
// Reverse navigation
/// <summary>
/// Child Products where [Product].[CategoryId] point to this entity (FK_Product_Category)
/// </summary>
public ICollection<Product> Products { get; set; } // Product.FK_Product_Category
public Category()
{
Products = new List<Product>();
}
}Note where it landed: at the top of the class, before the properties, and with the indentation exactly as you supplied it. The generator does not re-indent your text, which is why the sample above is indented one level less than the properties around it - the eight leading spaces in the string are what you get.
INotifyPropertyChanged on every entity, without a partial file per table:
Settings.WriteInsideClassBody = t =>
" public event PropertyChangedEventHandler PropertyChanged;" + Environment.NewLine +
" protected virtual void OnPropertyChanged([CallerMemberName] string name = null)" + Environment.NewLine +
" {" + Environment.NewLine +
" PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));" + Environment.NewLine +
" }" + Environment.NewLine;Add System.ComponentModel and System.Runtime.CompilerServices to
Settings.AdditionalNamespaces, and see
How to implement OnPropertyChanged for the full recipe.
A ToString() chosen by what the table has. Useful in debugging and in dropdown binding:
Settings.WriteInsideClassBody = t =>
{
var name = t.Columns.FirstOrDefault(c => c.NameHumanCase == "Name" || c.NameHumanCase.EndsWith("Name"));
return name == null ? string.Empty :
" public override string ToString() => " + name.NameHumanCase + ";" + Environment.NewLine;
};Interface members an interface you attached in Settings.UpdateTable requires.
Prefer a partial class where you can. If the code applies to one or two entities, set
Settings.EntityClassesModifiers = "public partial" and write a normal .cs file. It is real code with real
tooling - IntelliSense, refactoring, the compiler pointing at the right line. Strings in a .tt have none of
that. This callback earns its place when the code has to go on many entities.
You own the indentation and the line endings. Nothing is re-indented, and forgetting a trailing newline runs your last line into the first property.
Syntax errors surface in the generated file, with a line number that means nothing in your .tt. Write
the code in a real .cs file first, get it compiling, then wrap it in strings.
It runs for views too. Check t.IsView if that matters.
Verbatim strings do not help as much as you expect. A C# verbatim string in a .tt cannot contain the
#> sequence, and quoting inside it needs doubling. Concatenating normal strings with Environment.NewLine
is uglier but survives contact with T4.
- How to implement OnPropertyChanged - the full worked example
- Settings.UpdateTable - attributes and base classes, rather than members
-
Settings.EntityClassesModifiers - the
partialroute -
Settings.AdditionalNamespaces -
usinglines your injected code needs - Settings Callbacks | Settings Reference
- Settings A-Z - every setting, with a page each
- Common Settings Types Explained
- Settings Callbacks
- Settings runtime values and helpers
- Filtering
- Full Control Over the Generated Code
- Enum Generation from Table Data
- Owned Entities
- JSON column support
- Global Query Filters
- Extended Property Names Feature
- Partial Properties
- File-Scoped Namespaces
- Data Annotations
- Spatial Types
- HierarchyId
- RowVersion and TimeStamp columns
- Lazy Loading
- Stored proc result sets
- Custom File-Based Templates
- Extra entities via partial classes
- INotifyPropertyChanged
- Syntax colour for T4