CodeFirst uses the T4 template (you must have never used the stupid method, but also hope you can advise), codefirstt4
We all know that the T4 template is used to generate similar code.
Under the conditions of DBFirst and ModelFirst, we can easily obtain all entity classes and their names from. edmx, and generate similar code for us through the template we define and some traversal work.
But in CodeFirst mode, we do not have edmx. Where can we get all the class names? Do we need to write the Entity layer class names one by one into the array, Ten hundreds and thousands?
Solution Process:
1. Use reflection to get all class names and write this code segment to the T4 template.
Foreach (Type t in Assembly. load ("Entity "). getTypes () {// your operations on these class information // e. g: if (t. fullName = "Entity. baseEntity ") {} else {string fullName = t. fullName; int length = fullName. length; int index = fullName. lastIndexOf ('. '); string classname = fullName. substring (index + 1, length-index-1); nameStr + = (classname) + ",";}}
2. The result is that the Code above can load the Assembly and obtain all the class names. You can view the results by breakpoint. When we put this code in the T4 template, the error message is that the Assembly cannot be loaded. (I saw the text template at runtime and haven't tried whether the template is valid yet)
3. There is no way at last. I created a console program named HelpTool in the application. The code in the previous section is rewritten as follows in Main:
static void Main(string[] args) { using (StreamWriter writer = new StreamWriter("D:\\EntitiesNames.txt")) { string classNameStr = ""; foreach (Type t in Assembly.Load("Entity").GetTypes()) { if (t.FullName == "Entity.BaseEntity" || t.FullName == "Entity.DbContextFactory" || t.FullName == "Entity.WeDbContext") { } else { string fullName = t.FullName; int length = fullName.Length; int index = fullName.LastIndexOf('.'); string classname = fullName.Substring(index + 1, length - index - 1); classNameStr += (classname) + ","; } } writer.Write(""); writer.Write(classNameStr); //Console.WriteLine("WriteClassNameSuccessfully"); //Console.ReadKey(); } }
4. Clearly, I write it to a text file. Every time I modify an object class, I have to run my console application.
5. Read text files in the T4 template. For example:
Get the names of all object classes, store them in the array, and traverse to generate similar code.
<#@ template language="C#" debug="false" hostspecific="true"#><#@ include file="EF.Utility.CS.ttinclude"#><#@ output extension=".cs"#> <#string[] className=new string[]{""};using (StreamReader reader = new StreamReader("D:\\EntitiesNames.txt")) { string nameStr = reader.ReadToEnd(); int index=nameStr.LastIndexOf(','); nameStr=nameStr.Substring(0,index); className= nameStr.Split(','); }#>using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using DalFactory;using Entity;using s2s.IDAL;namespace s2s.UnitOfWork{ public partial class UnitWork{<#foreach (var entity in className){#> public I<#=entity#>Dal <#=entity#>Dal { get { return AbstractDalFactory.GetInstance("<#=entity#>Dal") as I<#=entity#>Dal; } }<#}#>}}
I know this method is very stupid. I cannot talk about a good solution. When encountering problems, coder can always propose various solutions.
I hope my friends in the garden can recommend good solutions and give me more advice.