日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

[转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

發布時間:2025/6/15 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html

〇、目錄

一、前言

二、工具準備

三、T4代碼生成預熱

  (一) 單文件生成:HelloWorld.cs

  (二) 多文件生成

四、生成數據層實體相關相似代碼

  (一) 生成準備

  (二) 生成實體相關相似代碼

  • 生成實體映射配置類
  • 生成實體倉儲接口
  • 生成實體倉儲實現
  • 五、源碼獲取

    系列導航

    一、前言

      經過前面EF的《第一篇》與《第二篇》,我們的數據層功能已經較為完善了,但有不少代碼相似度較高,比如負責實體映射的 EntityConfiguration,負責倉儲操作的IEntityRepository與EntityRepository。而且每添加一個實體類型,就要手動去添加一套相應的代碼,也是比較累的工作。如果能有一個根據實體類型自動生成這些相似度較高的代碼的解決方案,那將會減少大量的無聊的工作。

      VS提供的“文本模板”(俗稱T4)功能,就是一個較好的解決方案。要添加一個實體類型,只要把實體類型定義好,然后運行一下定義好的T4模板,就可以自動生成相應的類文件。

    二、工具準備

    ?  為了更好的使用 T4模板 功能,我們需要給VS安裝如下兩個插件:

    • Devart T4 Editor:為VS提供智能提示功能。
    • T4 Toolbox:在生成多文件時很有用。

    三、T4代碼生成預熱

    (一) 單文件生成:HelloWorld.cs

    ?  下面,我們先來體驗一個最簡單的T4代碼生成功能,輸出一個最簡單的類文件。

      首先,在 GMF.Demo.Core.Data中 添加一個名為 T4 的文件夾,用于存放生成本工程內的代碼的T4模板文件。并在其中添加一個名為 HelloWorld.tt的“文本模板”的項。

      HelloWorld.tt定義如下:

    1 <#@ template debug="false" hostspecific="false" language="C#" #> 2 <#@ assembly name="System.Core" #> 3 <#@ import namespace="System.Linq" #> 4 <#@ import namespace="System.Text" #> 5 <#@ import namespace="System.Collections.Generic" #> 6 <#@ output extension=".cs" #> 7 using System; 8 9 namespace GMF.Demo.Core.Data.T4 10 { 11 public class HelloWorld 12 { 13 private string _word; 14 15 public HelloWorld(string word) 16 { 17 _word = word; 18 } 19 } 20 }

    ?  直接保存文件(T4的生成將會在保存模板,模板失去焦點等情況下自動觸發生成。),將會在模板的當前位置生成一個同名的類文件:

      HelloWorld.cs的內容如下:

    1 using System; 2 3 namespace GMF.Demo.Core.Data.T4 4 { 5 public class HelloWorld 6 { 7 private string _word; 8 9 public HelloWorld(string word) 10 { 11 _word = word; 12 } 13 } 14 }

    ?  這樣,我們的HelloWorld之旅就結束了,非常簡單。

    (二) 多文件生成

      當前位置方案的方案只能生成如下所示的代碼:

      生成的文件會與T4模板在同一目錄中,這里就不詳述了,可以參考 蔣金楠?一個簡易版的T4代碼生成"框架"?。

      本項目的多文件需要生成到指定文件夾中,但又想對T4模板進行統一的管理,T4文件夾里放置T4模板文件,但生成的映射文件EntityConfiguration將放置到文件夾Configurations中,倉儲操作的文件IEntityRepository與EntityRepository將放置到Repositories文件夾中。且生成的代碼文件應能自動的添加到解決方案中,而不是只是在文件夾中存在。

      要實現此需求,一個簡單的辦法就是通過 T4 Toolbox 來進行生成。想了解 T4 Toolbox 的細節,可以自己使用 ILSpy 來對?T4Toolbox.dll 文件進行反編譯來查看源代碼,如果是通過 T4 Toolbox 是通過VS的插件來安裝的,將在“C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio\11.0\Extensions\dca4f0lt.jdx”文件夾中(我的機器上)。下面,我們直接進行多文件生成的演示。

      首先,添加一個名為 HelloWorldTemplate.tt 的?T4 Toolbox 的代碼模板。

      此模板將繼承于 T4 Toolbox 的 CSharpTemplate 類:

    1 <#+ 2 // <copyright file="HelloWorldTemplate.tt" company="郭明鋒@中國"> 3 // Copyright ? 郭明鋒@中國. All Rights Reserved. 4 // </copyright> 5 6 public class HelloWorldTemplate : CSharpTemplate 7 { 8 private string _className; 9 10 public HelloWorldTemplate(string className) 11 { 12 _className = className; 13 } 14 15 public override string TransformText() 16 { 17 #> 18 using System; 19 20 namespace GMF.Demo.Core.Data.T4 21 { 22 public class <#=_className #> 23 { 24 private string _word; 25 26 public <#=_className #>(string word) 27 { 28 _word = word; 29 } 30 } 31 } 32 <#+ 33 return this.GenerationEnvironment.ToString(); 34 } 35 } 36 #>

    ?  模板類中定義了一個 className 參數,用于接收一個表示要生成的類名的值。所有生成類的代碼都以字符串的形式寫在重寫的 TransformText 方法中。

      再定義一個T4模板文件?HelloWorldMulti.tt,用于調用 上面定義的代碼模板進行代碼文件的生成。

    1 <#@ template debug="false" hostspecific="false" language="C#" #> 2 <#@ assembly name="System.Core" #> 3 <#@ import namespace="System.IO" #> 4 <#@ import namespace="System.Linq" #> 5 <#@ import namespace="System.Text" #> 6 <#@ import namespace="System.Collections.Generic" #> 7 <#@ include file="T4Toolbox.tt" #> 8 <#@ include file="HelloWorldTemplate.tt" #> 9 <# 10 string curPath = Path.GetDirectoryName(Host.TemplateFile); 11 string destPath = Path.Combine(curPath, "outPath"); 12 if(!Directory.Exists(destPath)) 13 { 14 Directory.CreateDirectory(destPath); 15 } 16 string[] classNames = new[]{"HelloWorld1", "HelloWorld2", "HelloWorld3"}; 17 foreach(string className in classNames) 18 { 19 HelloWorldTemplate template = new HelloWorldTemplate(className); 20 string fileName = string.Format(@"{0}\{1}.cs", destPath, className); 21 template.Output.Encoding = Encoding.UTF8; 22 template.RenderToFile(fileName); 23 } 24 #>

      以上是整個T4模板的執行方,在執行方中,要引用所有需要用到的類庫文件,命名空間,包含的模板文件等。

      最后,文件的生成是調用 T4 Toolbox 的Template基類中定義的 RenderToFile(string filename)方法來生成各個文件的,輸入的參數為生成文件的文件全名。在這里,生成將如下所示:

      outPPath文件夾中生成了 HelloWorld1.cs、HelloWorld2.cs、HelloWorld3.cs 文件,而?HelloWorldMulti.tt 所在文件夾中也會生成一個空的?HelloWorldMulti.cs 類文件。

    四、生成數據層實體相關相似代碼

    (一) 生成準備

      我們的生成代碼是完全依賴于業務實體的,所以,需要有一個類來對業務實體的信息進行提取封裝。

    1 namespace GMF.Component.Tools.T42 {3 /// <summary>4 /// T4實體模型信息類5 /// </summary>6 public class T4ModelInfo7 {8 /// <summary>9 /// 獲取 模型所在模塊名稱 10 /// </summary> 11 public string ModuleName { get; private set; } 12 13 /// <summary> 14 /// 獲取 模型名稱 15 /// </summary> 16 public string Name { get; private set; } 17 18 /// <summary> 19 /// 獲取 模型描述 20 /// </summary> 21 public string Description { get; private set; } 22 23 public IEnumerable<PropertyInfo> Properties { get; private set; } 24 25 public T4ModelInfo(Type modelType) 26 { 27 var @namespace = modelType.Namespace; 28 if (@namespace == null) 29 { 30 return; 31 } 32 var index = @namespace.LastIndexOf('.') + 1; 33 ModuleName = @namespace.Substring(index, @namespace.Length - index); 34 Name = modelType.Name; 35 var descAttributes = modelType.GetCustomAttributes(typeof(DescriptionAttribute), true); 36 Description = descAttributes.Length == 1 ? ((DescriptionAttribute)descAttributes[0]).Description : Name; 37 Properties = modelType.GetProperties(); 38 } 39 } 40 }

    ?  另外,通過模板生成的代碼,與我們手寫的代碼有如下幾個區別:

  • 手寫代碼可以自由定義,生成代碼是根據模板生成的,必然遵守模板定義的規范。
  • 手寫代碼的修改可以永久保存,生成代碼的修改將會在下次生成后丟失,即生成代碼不應該進行修改。
  •   基于以上幾個區別,我提出如下解決方案,來解決生成代碼的修改問題

  • 通過模板生成的類應盡量定義為分部類(partial class),在需要進行修改及擴展的時候可以定義另外的同名分部類來進行修改。
  • 對于需要外部實現的功能,定義分部方法來對外提供擴展。
  • 生成代碼的類文件命名把擴展名由“.cs”更改為“generated.cs”,以區分生成代碼與手寫代碼文件。
  • (二) 生成實體相關相似代碼

      1. 生成實體映射配置類

      實體映射配置類模板 EntityConfigurationTemplate.tt?定義:

    1 <#+ 2 // <copyright file="EntityConfigurationTemplate.tt" company="郭明鋒@中國"> 3 // Copyright ? 郭明鋒@中國. All Rights Reserved. 4 // </copyright> 5 6 public class EntityConfigurationTemplate : CSharpTemplate 7 { 8 private T4ModelInfo _model; 9 10 public EntityConfigurationTemplate(T4ModelInfo model) 11 { 12 _model = model; 13 } 14 15 /// <summary> 16 /// 獲取 生成的文件名,根據模型名定義 17 /// </summary> 18 public string FileName 19 { 20 get 21 { 22 return string.Format("{0}Configuration.generated.cs", _model.Name); 23 } 24 } 25 26 public override string TransformText() 27 { 28 #> 29 //------------------------------------------------------------------------------ 30 // <auto-generated> 31 // 此代碼由工具生成。 32 // 對此文件的更改可能會導致不正確的行為,并且如果 33 // 重新生成代碼,這些更改將會丟失。 34 // 如存在本生成代碼外的新需求,請在相同命名空間下創建同名分部類實現 <#= _model.Name #>ConfigurationAppend 分部方法。 35 // </auto-generated> 36 // 37 // <copyright file="<#= _model.Name #>Configuration.generated.cs"> 38 // Copyright(c)2013 GMFCN.All rights reserved. 39 // CLR版本:4.0.30319.239 40 // 開發組織:郭明鋒@中國 41 // 公司網站:http://www.gmfcn.net 42 // 所屬工程:GMF.Demo.Core.Data 43 // 生成時間:<#= DateTime.Now.ToString("yyyy-MM-dd HH:mm") #> 44 // </copyright> 45 //------------------------------------------------------------------------------ 46 47 using System; 48 using System.Data.Entity.ModelConfiguration; 49 using System.Data.Entity.ModelConfiguration.Configuration; 50 51 using GMF.Component.Data; 52 using GMF.Demo.Core.Models; 53 54 55 namespace GMF.Demo.Core.Data.Configurations 56 { 57 /// <summary> 58 /// 實體類-數據表映射——<#= _model.Description #> 59 /// </summary> 60 internal partial class <#= _model.Name #>Configuration : EntityTypeConfiguration<<#= _model.Name #>>, IEntityMapper 61 { 62 /// <summary> 63 /// 實體類-數據表映射構造函數——<#= _model.Description #> 64 /// </summary> 65 public <#= _model.Name #>Configuration() 66 { 67 <#= _model.Name #>ConfigurationAppend(); 68 } 69 70 /// <summary> 71 /// 額外的數據映射 72 /// </summary> 73 partial void <#= _model.Name #>ConfigurationAppend(); 74 75 /// <summary> 76 /// 將當前實體映射對象注冊到當前數據訪問上下文實體映射配置注冊器中 77 /// </summary> 78 /// <param name="configurations">實體映射配置注冊器</param> 79 public void RegistTo(ConfigurationRegistrar configurations) 80 { 81 configurations.Add(this); 82 } 83 } 84 } 85 <#+ 86 return this.GenerationEnvironment.ToString(); 87 } 88 } 89 #>

    ?  生成模板調用方 EntityCodeScript.tt?定義

    1 <#@ template language="C#" debug="True" #> 2 <#@ output extension="cs" #> 3 <#@ Assembly Name="System.Core" #> 4 <#@ Assembly Name="$(SolutionDir)\GMF.Component.Tools\bin\Debug\GMF.Component.Tools.dll" #> 5 <#@ import namespace="System.IO" #> 6 <#@ Import Namespace="System.Linq" #> 7 <#@ Import Namespace="System.Text" #> 8 <#@ import namespace="System.Reflection" #> 9 <#@ Import Namespace="System.Collections.Generic" #> 10 <#@ Import Namespace="GMF.Component.Tools" #> 11 <#@ Import Namespace="GMF.Component.Tools.T4" #> 12 <#@ include file="T4Toolbox.tt" #> 13 <#@ include file="Include\EntityConfigurationTemplate.tt" #> 14 <# 15 string currentPath = Path.GetDirectoryName(Host.TemplateFile); 16 string projectPath =currentPath.Substring(0, currentPath.IndexOf(@"\T4")); 17 string solutionPath = currentPath.Substring(0, currentPath.IndexOf(@"\GMF.Demo.Core.Data")); 18 19 string modelFile= Path.Combine(solutionPath, @"GMF.Demo.Core.Models\bin\Debug\GMF.Demo.Core.Models.dll"); 20 byte[] fileData= File.ReadAllBytes(modelFile); 21 Assembly assembly = Assembly.Load(fileData); 22 IEnumerable<Type> modelTypes = assembly.GetTypes().Where(m => typeof(Entity).IsAssignableFrom(m) && !m.IsAbstract); 23 foreach(Type modelType in modelTypes) 24 { 25 T4ModelInfo model = new T4ModelInfo(modelType); 26 //實體映射類 27 EntityConfigurationTemplate config = new EntityConfigurationTemplate(model); 28 string path = string.Format(@"{0}\Configurations", projectPath); 29 config.Output.Encoding = Encoding.UTF8; 30 config.RenderToFile(Path.Combine(path, config.FileName)); 31 } 32 #>

      調用方通過反射從業務實體程序集 GMF.Demo.Core.Models.dll 中獲取所有基類為 Entity 的并且不是抽象類的實體類型信息,再調用模板逐個生成實體配置類文件。

      例如,生成的登錄記錄信息(LoginLog)的映射文件 LoginLogConfiguration.generated.cs?如下:

    1 //------------------------------------------------------------------------------ 2 // <auto-generated> 3 // 此代碼由工具生成。 4 // 對此文件的更改可能會導致不正確的行為,并且如果 5 // 重新生成代碼,這些更改將會丟失。 6 // 如存在本生成代碼外的新需求,請在相同命名空間下創建同名分部類實現 LoginLogConfigurationAppend 分部方法。 7 // </auto-generated> 8 // 9 // <copyright file="LoginLogConfiguration.generated.cs"> 10 // Copyright(c)2013 GMFCN.All rights reserved. 11 // CLR版本:4.0.30319.239 12 // 開發組織:郭明鋒@中國 13 // 公司網站:http://www.gmfcn.net 14 // 所屬工程:GMF.Demo.Core.Data 15 // 生成時間:2013-06-16 17:45 16 // </copyright> 17 //------------------------------------------------------------------------------ 18 19 using System; 20 using System.Data.Entity.ModelConfiguration; 21 using System.Data.Entity.ModelConfiguration.Configuration; 22 23 using GMF.Component.Data; 24 using GMF.Demo.Core.Models; 25 26 27 namespace GMF.Demo.Core.Data.Configurations 28 { 29 /// <summary> 30 /// 實體類-數據表映射——登錄記錄信息 31 /// </summary> 32 internal partial class LoginLogConfiguration : EntityTypeConfiguration<LoginLog>, IEntityMapper 33 { 34 /// <summary> 35 /// 實體類-數據表映射構造函數——登錄記錄信息 36 /// </summary> 37 public LoginLogConfiguration() 38 { 39 LoginLogConfigurationAppend(); 40 } 41 42 /// <summary> 43 /// 額外的數據映射 44 /// </summary> 45 partial void LoginLogConfigurationAppend(); 46 47 /// <summary> 48 /// 將當前實體映射對象注冊到當前數據訪問上下文實體映射配置注冊器中 49 /// </summary> 50 /// <param name="configurations">實體映射配置注冊器</param> 51 public void RegistTo(ConfigurationRegistrar configurations) 52 { 53 configurations.Add(this); 54 } 55 } 56 }

      要配置登錄信息與用戶信息的 N:1 關系,只需要添加一個分部類?LoginLogConfiguration,并實現分類方法?LoginLogConfigurationAppend 即可。

    1 namespace GMF.Demo.Core.Data.Configurations 2 { 3 partial class LoginLogConfiguration 4 { 5 partial void LoginLogConfigurationAppend() 6 { 7 HasRequired(m => m.Member).WithMany(n => n.LoginLogs); 8 } 9 } 10 }

      2. 生成實體倉儲接口

      實體映射配置類模板 EntityConfigurationTemplate.tt?定義:

    1 <#+ 2 // <copyright file="IEntityRepositoryTemplate.tt" company="郭明鋒@中國"> 3 // Copyright ? 郭明鋒@中國. All Rights Reserved. 4 // </copyright> 5 6 public class IEntityRepositoryTemplate : CSharpTemplate 7 { 8 private T4ModelInfo _model; 9 10 public IEntityRepositoryTemplate(T4ModelInfo model) 11 { 12 _model = model; 13 } 14 15 /// <summary> 16 /// 獲取 生成的文件名,根據模型名定義 17 /// </summary> 18 public string FileName 19 { 20 get 21 { 22 return string.Format("I{0}Repository.generated.cs", _model.Name); 23 } 24 } 25 26 public override string TransformText() 27 { 28 #> 29 //------------------------------------------------------------------------------ 30 // <auto-generated> 31 // 此代碼由工具生成。 32 // 對此文件的更改可能會導致不正確的行為,并且如果 33 // 重新生成代碼,這些更改將會丟失。 34 // 如存在本生成代碼外的新需求,請在相同命名空間下創建同名分部類進行實現。 35 // </auto-generated> 36 // 37 // <copyright file="I<#= _model.Name #>Repository.generated.cs"> 38 // Copyright(c)2013 GMFCN.All rights reserved. 39 // CLR版本:4.0.30319.239 40 // 開發組織:郭明鋒@中國 41 // 公司網站:http://www.gmfcn.net 42 // 所屬工程:GMF.Demo.Core.Data 43 // 生成時間:<#= DateTime.Now.ToString("yyyy-MM-dd HH:mm") #> 44 // </copyright> 45 //------------------------------------------------------------------------------ 46 47 using System; 48 49 using GMF.Component.Data; 50 using GMF.Demo.Core.Models; 51 52 53 namespace GMF.Demo.Core.Data.Repositories 54 { 55 /// <summary> 56 /// 數據訪問層接口——<#= _model.Description #> 57 /// </summary> 58 public partial interface I<#= _model.Name #>Repository : IRepository<<#= _model.Name #>> 59 { } 60 } 61 62 <#+ 63 return this.GenerationEnvironment.ToString(); 64 } 65 } 66 #>

    ?  相應的,在調用方?EntityCodeScript.tt 中添加模板調用代碼(如下 11-15 行所示):

    1 foreach(Type modelType in modelTypes) 2 { 3 T4ModelInfo model = new T4ModelInfo(modelType); 4 5 //實體映射類 6 EntityConfigurationTemplate config = new EntityConfigurationTemplate(model); 7 string path = string.Format(@"{0}\Configurations", projectPath); 8 config.Output.Encoding = Encoding.UTF8; 9 config.RenderToFile(Path.Combine(path, config.FileName)); 10 11 //實體倉儲操作接口 12 IEntityRepositoryTemplate irep= new IEntityRepositoryTemplate(model); 13 path = string.Format(@"{0}\Repositories", projectPath); 14 irep.Output.Encoding = Encoding.UTF8; 15 irep.RenderToFile(Path.Combine(path, irep.FileName)); 16 }

    ?

      生成的登錄記錄信息倉儲操作接口 ILoginLogRepository.generated.cs:

    1 //------------------------------------------------------------------------------ 2 // <auto-generated> 3 // 此代碼由工具生成。 4 // 對此文件的更改可能會導致不正確的行為,并且如果 5 // 重新生成代碼,這些更改將會丟失。 6 // 如存在本生成代碼外的新需求,請在相同命名空間下創建同名分部類進行實現。 7 // </auto-generated> 8 // 9 // <copyright file="ILoginLogRepository.generated.cs"> 10 // Copyright(c)2013 GMFCN.All rights reserved. 11 // CLR版本:4.0.30319.239 12 // 開發組織:郭明鋒@中國 13 // 公司網站:http://www.gmfcn.net 14 // 所屬工程:GMF.Demo.Core.Data 15 // 生成時間:2013-06-16 17:56 16 // </copyright> 17 //------------------------------------------------------------------------------ 18 19 using System; 20 21 using GMF.Component.Data; 22 using GMF.Demo.Core.Models; 23 24 25 namespace GMF.Demo.Core.Data.Repositories 26 { 27 /// <summary> 28 /// 數據訪問層接口——登錄記錄信息 29 /// </summary> 30 public partial interface ILoginLogRepository : IRepository<LoginLog> 31 { } 32 }

      如果 IRepository<T> 中定義的倉儲操作不滿足登錄記錄倉儲操作的需求,只需要添加一個相應的分部接口,在其中進行需求的定義即可。這里當前沒有額外的需求,就不需要額外定義了。

      3. 生成實體倉儲實現

      實體倉儲操作的實現與倉儲操作接口類似,這里略過。

      完成生成后,代碼結構如下所示:

      如果添加了或者刪除了一個實體,只需要重新運行一下調用模板?EntityCodeScript.tt 即可重新生成新的代碼。

    五、源碼獲取

      為了讓大家能第一時間獲取到本架構的最新代碼,也為了方便我對代碼的管理,本系列的源碼已加入微軟的開源項目網站 http://www.codeplex.com,地址為:

      https://gmframework.codeplex.com/

      可以通過下列途徑獲取到最新代碼:

    • 如果你是本項目的參與者,可以通過VS自帶的團隊TFS直接連接到?https://tfs.codeplex.com:443/tfs/TFS17 獲取最新代碼
    • 如果你安裝有SVN客戶端(親測TortoiseSVN 1.6.7可用),可以連接到?https://gmframework.svn.codeplex.com/svn 獲取最新代碼
    • 如果以上條件都不滿足,你可以進入頁面?https://gmframework.codeplex.com/SourceControl/latest 查看最新代碼,也可以點擊頁面上的?Download 鏈接進行壓縮包的下載,你還可以點擊頁面上的 History 鏈接獲取到歷史版本的源代碼
    • 如果你想和大家一起學習MVC,學習EF,歡迎加入Q群:5008599(群發言僅限技術討論,拒絕閑聊,拒絕醬油,拒絕廣告)
    • 如果你想與我共同來完成這個開源項目,可以隨時聯系我。

    系列導航

  • MVC實用架構設計(〇)——總體設計
  • MVC實用架構設計(一)——項目結構搭建
  • MVC實用架構設計(二)——使用MEF應用IOC
  • MVC實用架構設計(三)——EF-Code First(1):Repository,UnitOfWork,DbContext
  • MVC實用架構設計(三)——EF-Code First(2):實體映射、數據遷移,重構
  • MVC實用架構設計(三)——EF-Code First(3):使用T4模板生成相似代碼
  • MVC實用架構設計(三)——EF-Code First(4):數據查詢
  • MVC實用架構設計(三)——EF-Code First(5):二級緩存
  • MVC實體架構設計(三)——EF-Code First(6):數據更新
  • 未完待續。。。
  • 如果您看完本篇文章感覺不錯,請點擊一下右下角的【推薦】來支持一下博主,謝謝!
    作者:郭明鋒 出處:http://www.cnblogs.com/guomingfeng

    本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

    ?

    總結

    以上是生活随笔為你收集整理的[转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产乱xxⅹxx国语对白 | 美女被草出白浆 | 日韩欧美电影一区二区三区 | 国产精品天天看 | 日本一区久久 | 国产a国产片国产 | 国产精品av免费观看 | 一级艳片新婚之夜 | 日本一区二区三区视频在线 | 精品日韩制服无码久久久久久 | 亚洲欧美激情在线观看 | 看黄网站在线 | 欧美男人亚洲天堂 | 91亚洲国产成人精品性色 | 日本成人网址 | 精品国产一区二区三区噜噜噜 | 日韩av毛片 | 日韩国产欧美在线视频 | 调教丰满的已婚少妇在线观看 | 日本一二三区不卡 | 玉足调教丨vk24分钟 | 91精品国自产 | 99re视频在线 | 成人欧美激情 | 国产成人在线观看免费 | 亚洲影院中文字幕 | 美女国产视频 | www欧美精品| 97精品视频在线观看 | 亚洲视频免费 | 国产尻逼视频 | 中文字幕精品三级久久久 | 四虎影院在线看 | 国产精品无码影院 | 最新日韩av在线 | 91高清视频 | 蜜桃av一区二区 | 国产一区二区免费 | 国产欧美又粗又猛又爽 | 香蕉久久夜色精品 | 无码人妻丰满熟妇区毛片18 | 久久嗨 | 午夜精品在线视频 | 亚洲视频免费播放 | 蜜桃91丨九色丨蝌蚪91桃色 | 欧美精品久久久久久久 | 国产片在线 | 亚洲成人诱惑 | 日韩有码电影 | 成人免费网站黄 | 欧美成人精品一区二区免费看片 | 亚洲成年人在线 | 性高跟鞋xxxxhd国产电影 | 亚洲福利一区二区 | 毛片女人 | 亚洲综合色在线 | 免费中文字幕在线观看 | 成年人免费网站 | 亚洲欧美日韩色图 | 特级精品毛片免费观看 | 日本色www | 夜夜春影院| 亚洲天堂五月 | 波多野结衣黄色网址 | 国产91亚洲 | 黄瓜视频色版 | 日本 奴役 捆绑 受虐狂xxxx | 本道综合精品 | 女女高潮h冰块play失禁百合 | av片在线观看网站 | 日本成人免费网站 | 欧美暧暧视频 | 国产伦人伦偷精品视频 | 亚洲欧洲精品成人久久奇米网 | 第一章婶婶的性事 | 中文字幕乱码人妻一区二区三区 | 超碰激情 | 91久久国产综合久久91精品网站 | 五月依人网 | 国产精品亚洲一区 | 精品一区国产 | 少妇免费毛片久久久久久久久 | 亚洲综合五月天婷婷丁香 | 在线va| av国产一区二区 | 国产精品第8页 | 日本精品视频网站 | 免费在线色 | 宅男视频污 | 伊人黄色| 欧美成人精品欧美一级乱 | 国产一区二区波多野结衣 | 黑人玩弄人妻一区二区三区免费看 | 成为性瘾网黄的yy对象后 | 男男h黄动漫啪啪无遮挡软件 | 亚洲色图18p| 色哟哟在线 | 女性裸体瑜伽无遮挡 | 另类小说欧美 |