データベースのテーブルやビューなどデータをマッピングするエンティティクラスは、O/Rマッパーを使用してデータベースのデータを操作するアプリケーションには必要になります。
そこで今回は、データベースのオブジェクトからエンティティクラスのソースコードを自動生成するプログラム(アプリケーション)を作ってみたいと思います。
作成するプログラムではデータベースのテーブルやビューの構造をクラスのオブジェクトに変換します。テーブルやビューの列はクラスのプロパティとして設定されます。
データベースはSQLServer、ソースコードの言語は.NET FrameworkのC#にします。
ユーザーインターフェース(UI)はWindows フォーム アプリケーションで作成します。
Visual StudioでC#のプロジェクトを新規作成します。
プロジェクトのテンプレートは「Windows フォーム アプリケーション (.NET Framework)」を選択します。
目次
ユーザーインターフェース(UI)
作成するフォームのデザインは次のようになります。
フォームには以下のコントロールを配置します。
コントロール | 名前 | 設定 |
---|---|---|
Form | EntityClassCodeGenerator | Text: “エンティティクラスコード生成” |
Label | label1 | Text: “スキーマ(&S):” |
ComboBox | cboSchema | Text: “” |
Label | label2 | Text: “オブジェクト(&O):” |
RadioButton | rdoTable | Text: “テーブル(&T)” |
RadioButton | rdoView | Text: “ビュー(&V)” |
RadioButton | rdoBoth | Text: “両方(&B)” |
Label | label3 | Text: “テーブル/ビュー(&E):” |
ComboBox | cboEntity | Text: “” |
Label | label4 | Text: “クラス名(&N):” |
TextBox | txtClassName | Text: “” |
Label | label5 | Text: “オプション(&I):” |
CheckBox | chkPublic | Text: “クラスのアクセス修飾子をPublicにする(&P)” |
CheckBox | chkComment | Text: “コメント用XMLを出力する(&X)” |
CheckBox | chkRead | Text: “クラス名にReadを付加する(&R)” |
CheckBox | chkDto | Text: “クラス名にDtoを付加する(&D)” |
CheckBox | chkPrivateSet | Text: “プロパティを読み取り専用にする (setアクセサーをprivateにする) (&A)” |
Button | btnCreate | Text: “作成(&M)” |
Button | btnCopy | Text: “コピー(&C)” |
TextBox | txtEntityClassCode | Multiline: true ScrollBars: Both Text: “””” |
エンティティクラスは通常のクラスと、読み取り専用(Read)のクラスと、DTO(Data Transfer Object: データ トランスファー オブジェクト)のクラスを生成できるようにしています。
クラスのアクセス修飾子は「クラスのアクセス修飾子をPublicにする」が選択(チェック)されていればpublicにし、未選択(チェックされていない)であればprotected internalで生成します。
クラスのプロパティ(テーブルの列)のsetアクセサはprivateにするかどうかを指定可能にしています。
クラス、プロパティにはXML Documentコメントを記載するための「///」から始まるコメント書式を出力するかどうかも指定可能にしています。
ソースコード
ソースコードはフォームクラスとWindowsフォームプロジェクトを作成すると生成されるApp.config、Programクラスの他に、データベースアクセス用クラス、データ型(名称)変換クラス、命名規則(名称)変換クラス、コード生成T4テキストテンプレートを作成します。
フォーム EntityClassCodeGeneratorForm.cs
フォームクラスは配置したコントロールのイベントでそれぞれの操作を行う処理を記述していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace EntityClassCodeGenerator { /// <summary> /// エンティティクラスコード生成フォーム。 /// </summary> public partial class EntityClassCodeGeneratorForm : Form { /// <summary> /// コンストラクタ。 /// </summary> public EntityClassCodeGeneratorForm() { InitializeComponent(); // コントロールの初期設定 Font = SystemFonts.CaptionFont; cboSchema.DropDownStyle = ComboBoxStyle.DropDownList; rdoTable.Checked = true; cboEntity.DropDownStyle = ComboBoxStyle.DropDownList; chkPublic.Checked = true; chkComment.Checked = true; txtEntityClassCode.Font = new Font( "MS ゴシック", 9.75F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(128))); // イベントの割り当て cboSchema.SelectedIndexChanged += CboSchema_SelectedIndexChanged; rdoTable.CheckedChanged += RdoTableAndView_CheckedChanged; rdoView.CheckedChanged += RdoTableAndView_CheckedChanged; rdoBoth.CheckedChanged += RdoTableAndView_CheckedChanged; cboEntity.SelectedIndexChanged += CboEntity_SelectedIndexChanged; chkRead.CheckedChanged += ChkRead_CheckedChanged; chkDto.CheckedChanged += ChkDto_CheckedChanged; btnCreate.Click += BtnCreate_Click; btnCopy.Click += BtnCopy_Click; // フィールドの初期化 _accessor = new DatabaseAccessor(); } /// <summary> /// データベースアクセスクラス。 /// </summary> private readonly DatabaseAccessor _accessor; /// <summary> /// OnLoadメソッドのオーバーライド /// </summary> /// <param name="e"></param> protected override void OnLoad(EventArgs e) { try { base.OnLoad(e); // スキーマの一覧をコンボボックスに設定する List<string> schemas = _accessor.GetSchemas(); cboSchema.DataSource = schemas; } catch (Exception ex) { MessageBox.Show(ex.Message); } } #region 処理メソッド /// <summary> /// テーブルリストを設定する。 /// </summary> private void SetTableList() { cboEntity.DataSource = null; cboEntity.Items.Add("dummy"); cboEntity.Items.Clear(); var schema = cboSchema.Text; List<string> entities = new List<string>(); if (rdoTable.Checked || rdoBoth.Checked) { // テーブルの一覧を取得 entities.AddRange(_accessor.GetTables(schema)); } if (rdoView.Checked || rdoBoth.Checked) { // ビューの一覧を取得 entities.AddRange(_accessor.GetViews(schema)); } // テーブル/ビューの一覧をコンボボックスに設定する cboEntity.DataSource = entities; } /// <summary> /// クラス名を設定する。 /// </summary> private void SetClassName() { var tableName = cboEntity.Text; var className = NamingRulesConveter.ToPascalTableName(tableName); if (chkRead.Checked) { className += "Read"; } if (chkDto.Checked) { className += "Dto"; } txtClassName.Text = className; } /// <summary> /// データベースのオブジェクトをもとにエンティティクラスを作成する。 /// </summary> private void CreateEntityClassFromDatabaseObject() { var schema = cboSchema.Text; var tableName = cboEntity.Text; var isPublic = chkPublic.Checked; var isRead = chkRead.Checked; var isDto = chkDto.Checked; var hasComment = chkComment.Checked; var isPrivateSet = chkPrivateSet.Checked; // データベースに接続して対象テーブル/ビューの列定義情報を取得する var dataSource = _accessor.GetTableSchema(schema, tableName); // テキストテンプレートクラスの生成 var template = new EntityClassCodeTemplate { TableName = tableName, DataSource = dataSource, IsPublic = isPublic, IsRead = isRead, IsDto = isDto, HasComment = hasComment, IsPrivateSet = isPrivateSet, }; // T4テキストテンプレートの変換メソッドで文字列型に変換する var context = template.TransformText(); // テキストボックスにエンティティクラスのコードを設定する txtEntityClassCode.Text = context; // クリップボードにコピーする CopyClassCodeText(); } /// <summary> /// エンティティクラスコードをクリップボードにコピーする。 /// </summary> private void CopyClassCodeText() { if (!string.IsNullOrWhiteSpace(txtEntityClassCode.Text)) { // クリップボードにコピー Clipboard.SetText(txtEntityClassCode.Text.TrimEnd()); } } #endregion #region イベントハンドラーメソッド /// <summary> /// スキーマコンボボックス選択インデックス変更時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void CboSchema_SelectedIndexChanged(object sender, EventArgs e) { try { SetTableList(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// テーブル/ビューチェック値変更時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void RdoTableAndView_CheckedChanged(object sender, EventArgs e) { try { SetTableList(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// テーブルコンボボックス選択インデックス変更時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void CboEntity_SelectedIndexChanged(object sender, EventArgs e) { try { SetClassName(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// Readチェックボックスチェック値変更時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void ChkRead_CheckedChanged(object sender, EventArgs e) { try { if (chkRead.Checked) { chkPrivateSet.Checked = true; } SetClassName(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// Dtoチェックボックスチェック値変更時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void ChkDto_CheckedChanged(object sender, EventArgs e) { try { if (chkDto.Checked) { chkPrivateSet.Checked = false; } SetClassName(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// 作成ボタンクリック時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void BtnCreate_Click(object sender, EventArgs e) { try { // データベースのオブジェクトをもとにエンティティクラスを作成する CreateEntityClassFromDatabaseObject(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// コピーボタンクリック時のイベント。 /// </summary> /// <param name="sender">イベントを発生させたオブジェクトへの参照</param> /// <param name="e">イベント引数</param> private void BtnCopy_Click(object sender, EventArgs e) { try { // クリップボードにコピーする CopyClassCodeText(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } #endregion } } |
フォームのロード時にスキーマ名の一覧をデータベースから取得して「スキーマ」コンボボックスのリストアイテムに設定します。
オブジェクトは選択されているスキーマのオブジェクトを対象に取得して「テーブル/ビュー」コンボボックスのリストアイテムに設定します。
オブジェクトは「テーブル」「ビュー」「両方」から選択可能で「テーブル」選択時はテーブルのみ「ビュー」選択時はビューのみ「両方」選択時はテーブルとビューの両方をコンボボックスのリストアイテムに設定します。
「スキーマ」コンボボックスでスキーマが変更された時には、テーブルおよびビューのオブジェクトを取得して「テーブル/ビュー」コンボボックスのリストアイテムに設定します。
「テーブル/ビュー」コンボボックスのオブジェクトが変更された時に、クラス名を「クラス名」テキストボックスに表示します。
エンティティクラスのコード生成は「作成」ボタンクリック時に行います。ソースコードの作成処理ではオプションで選択されている条件に基づいて、選択されているデータベースのオブジェクトの定義情報をエンティティクラスに変換したコードを生成します。
オプションとして用意している「クラス名にReadを付加する」チェックボックスがチェックされている場合は読み取り専用クラスとして「プロパティを読み取り専用にする (setアクセサーをprivateにする)」のチェックボックスをチェックします。「クラス名にDtoを付加する」チェックボックスがチェックされている場合は「プロパティを読み取り専用にする (setアクセサーをprivateにする)」のチェックボックスのチェックをはずします。
データベースアクセス DatabaseAccessor.cs
データベースアクセスクラスはデータベースに接続してスキーマ、テーブル、ビューの一覧と、指定したテーブルやビューの列定義情報を取得します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace EntityClassCodeGenerator { /// <summary> /// データベースアクセスクラス。 /// </summary> internal class DatabaseAccessor { /// <summary> /// テーブル名/ビュー名を条件にカラム情報を取得する。 /// </summary> /// <param name="schema">スキーマ</param> /// <param name="tableName">テーブル名</param> /// <returns>列情報が設定されたDataTable</returns> internal DataTable GetTableSchema(string schema, string tableName) { DataTable result = null; // 接続文字列をconfigファイルから取得 var connectionString = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString; // データベースに接続 using (var connection = new SqlConnection(connectionString)) { connection.Open(); using (var command = new SqlCommand()) { command.Connection = connection; command.CommandType = CommandType.Text; // 対象テーブルの全カラムを選択するSQLを設定 command.CommandText = $"SELECT * FROM {schema}.{tableName}"; var dataAdapter = new SqlDataAdapter(command); // 列情報のみ取得 var dataSet = new DataSet(); dataAdapter.FillSchema(dataSet, SchemaType.Source); // テーブルの結果を戻り値に設定する if (dataSet.Tables.Count > 0) { result = dataSet.Tables[0]; } } connection.Close(); } return result; } /// <summary> /// テーブル/ビューのデータを取得する。 /// </summary> /// <param name="sql">SQL文字列</param> /// <returns>取得したデータを格納したDataTable</returns> internal DataTable GetTableData(string sql) { DataTable result = new DataTable(); // 接続文字列をconfigファイルから取得 var connectionString = ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString; // データベースに接続 using (var connection = new SqlConnection(connectionString)) { connection.Open(); using (var command = new SqlCommand()) { command.Connection = connection; command.CommandType = CommandType.Text; // 対象テーブルの全カラムを選択するSQLを設定 command.CommandText = sql; var dataAdapter = new SqlDataAdapter(command); // データ取得 dataAdapter.Fill(result); } connection.Close(); } return result; } /// <summary> /// スキーマの一覧を取得する。 /// </summary> /// <returns>スキーマ名のリスト</returns> internal List<string> GetSchemas() { // システムカタログビューのsys.schemasからスキーマの一覧を取得 // スキーマ名が「INFORMATION_SCHEMA」「db_~」「guest」「sys」は除く string sql = $@" SELECT schemas.name FROM sys.schemas WHERE schemas.name != 'INFORMATION_SCHEMA' AND schemas.name NOT LIKE 'db[_]%' AND schemas.name != 'guest' AND schemas.name != 'sys' ORDER BY schemas.name"; // スキーマ一覧のデータを取得する DataTable dataTable = GetTableData(sql); // 取得した結果を戻り値に設定する List<string> result = new List<string>(); foreach (DataRow row in dataTable.Rows) { var name = row["name"].ToString(); result.Add(name); } return result; } /// <summary> /// テーブルの一覧を取得する。 /// </summary> /// <param name="schema">スキーマ名</param> /// <returns>テーブル名のリスト</returns> internal List<string> GetTables(string schema) { string sql = $@" SELECT tables.name FROM sys.tables WHERE SCHEMA_NAME(tables.schema_id) = '{schema}' ORDER BY tables.name "; // テーブル一覧のデータを取得する DataTable dataTable = GetTableData(sql); // 取得した結果を戻り値に設定する List<string> result = new List<string>(); foreach (DataRow row in dataTable.Rows) { var name = row["name"].ToString(); result.Add(name); } return result; } /// <summary> /// ビューの一覧を取得する。 /// </summary> /// <param name="schema">スキーマ名</param> /// <returns>ビュー名のリスト</returns> internal List<string> GetViews(string schema) { string sql = $@" SELECT views.name FROM sys.views WHERE SCHEMA_NAME(views.schema_id) = '{schema}' ORDER BY views.name "; // ビュー一覧のデータを取得する DataTable dataTable = GetTableData(sql); // 取得した結果を戻り値に設定する List<string> result = new List<string>(); foreach (DataRow row in dataTable.Rows) { var name = row["name"].ToString(); result.Add(name); } return result; } } } |
データ型変換 DataTypeConveter.cs
データ型変換クラスはDataAdapterクラスのFillSchemaメソッドで取得されるデータ型をエイリアス(別名)形式に変換します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
using System; using System.Collections.Generic; //using System.Linq; //using System.Text; //using System.Threading.Tasks; namespace EntityClassCodeGenerator { /// <summary> /// データ型変換クラス。 /// </summary> public static class DataTypeConveter { /// <summary> /// 型名を別名(Int32 → int, String → string など)に変換する。 /// </summary> /// <param name="dataTypeName">データ型の名前</param> /// <param name="allowDBNull">Null許容型を設定するかどうか</param> /// <returns>変換後のデータ型の名前。</returns> public static string ConvertTypeName(string dataTypeName, bool allowDBNull) { var isAppendNull = false; // 変換するデータ型のリスト Dictionary<string, string> types = new Dictionary<string, string>() { {"Int64", "long"}, {"Byte", "byte"}, {"Byte[]", "byte[]"}, {"Boolean", "bool"}, {"String", "string"}, {"DateTime", "DateTime"}, {"DateTimeOffset", "DateTimeOffset"}, {"Decimal", "decimal"}, {"Double", "double"}, {"Int32", "int"}, {"Int16", "short"}, {"Single", "float"}, {"Object", "object"}, {"TimeSpan", "TimeSpan"}, {"Guid", "Guid"}, {"Microsoft.SqlServer.Types.SqlGeography", "Microsoft.SqlServer.Types.SqlGeography"}, {"Microsoft.SqlServer.Types.SqlGeometry", "Microsoft.SqlServer.Types.SqlGeometry"}, {"Microsoft.SqlServer.Types.SqlHierarchyId", "Microsoft.SqlServer.Types.SqlHierarchyId"} }; // Null許容型のあるデータ型のリスト List<string> nullableTypes = new List<string>() { "long", "byte", "bool", "DateTime", "DateTimeOffset", "decimal", "int", "short", "TimeSpan", "Guid" }; string typeName = ""; try { typeName = types[dataTypeName]; if (isAppendNull) { if (allowDBNull && nullableTypes.Contains(typeName)) { typeName += "?"; } } } catch (Exception ex) { string s = ex.Message; } return typeName; } } } |
命名規則変換 NamingRulesConveter
命名規則変換クラスは、データベースのオブジェクト名をエンティティクラスのオブジェクト名に変換します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
using System; //using System.Collections.Generic; //using System.Linq; //using System.Text; //using System.Threading.Tasks; using System.Text.RegularExpressions; namespace EntityClassCodeGenerator { /// <summary> /// 命名規則変換クラス /// </summary> public static class NamingRulesConveter { /// <summary> /// コンスタントケース(大文字スネークケース)をキャメルケースに変換する /// </summary> /// <param name="text"></param> /// <returns></returns> public static string ToCamel(string text) { return Regex.Replace( text.ToLower(), @"_\w", match => match.Value.ToUpper().Replace("_", string.Empty)); } /// <summary> /// コンスタントケース(大文字スネークケース)をパスカルケースに変換する /// </summary> /// <param name="text"></param> /// <returns></returns> public static string ToPascal(string text) { // いったんキャメルケースに変換 text = ToCamel(text); return Regex.Replace( text, @"^\w", match => match.Value.ToUpper()); } /// <summary> /// テーブル名をパスカルケースに変換する。 /// </summary> /// <param name="tableName">テーブル名</param> /// <returns>変換後のテーブル名</returns> public static string ToPascalTableName(string tableName) { if (tableName.ToUpper().StartsWith("D_") || tableName.ToUpper().StartsWith("M_") || tableName.ToUpper().StartsWith("T_") || tableName.ToUpper().StartsWith("V_")) { // 先頭が「D_」「M_」「T_」「V_」の場合は除去する tableName = tableName.Substring(2); } // パスカルケースに変換する return ToPascal(tableName); } } } |
ここではデータベースのオブジェクト(テーブル、ビュー、列など)の名前がコンスタントケース(大文字スネークケース)で作成されていたり、テーブル名またはビュー名の先頭に「D_」「M_」「T_」「V_」があることを想定しています。
テーブル名またはビュー名の先頭に「D_」「M_」「T_」「V_」がある場合は除去してクラス名に変換します。
クラス名(テーブル名)、クラスのプロパティ名(テーブルの列名)はパスカルケースに変換します。
(例)T_TABLE_NAME → TableName
コード自動生成T4テンプレート EntityClassCodeTemplate.tt
コードを生成するT4テキストテンプレートでフォーム(画面)で指定された条件に応じてソースコードを生成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ assembly name="System.Data" #> <#@ import namespace="System.Data" #> <#@ assembly name="$(SolutionDir)\EntityClassCodeGenerator\bin\debug\EntityClassCodeGenerator.exe" #> <#@ import namespace="EntityClassCodeGenerator" #> <#@ output extension=".cs" #> <# if (this.dataSource == null) { return string.Empty; } #> <#= this.IsPublic ? "public" : "protected internal" #> class <#= NamingRulesConveter.ToPascalTableName(this.TableName) #><#= this.IsRead ? "Read" : "" #><#= this.IsDto ? "Dto" : "" #> { <# foreach(DataColumn column in this.dataSource.Columns) { #> <# if (this.HasComment) { #> /// <summary> /// /// </summary> <# } #> public <#= DataTypeConveter.ConvertTypeName(column.DataType.Name, column.AllowDBNull) #> <#= NamingRulesConveter.ToPascal(column.ColumnName) #> { get; <#= this.IsPrivateSet ? "private " : "" #>set; } <# } #> } <#+ private DataTable dataSource = null; public DataTable DataSource { set { this.dataSource = value; } } public string TableName { set; get; } public bool IsPublic { set; get; } public bool IsRead { set; get; } public bool IsDto { set; get; } public bool HasComment { set; get; } public bool IsPrivateSet { set; get; } #> |
アプリケーションコンフィグ App.config
アプリケーションコンフィグにはデータベースへの接続文字列を記載します。
configurationセクションにconnectionStringsセクションを追加し、connectionStringsの要素にデータベースへの接続文字列を追加します。
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" /> </startup> <connectionStrings> <add name="sqlserver" connectionString="Data Source=[データベースサーバー];Initial Catalog=[データベース名];Integrated Security=True"/> </connectionStrings> </configuration> |
[データベースサーバー]の部分に接続するサーバーの名前やIP+インスタンス名(localhost, SERVER\SQLSERVER2017, 127.0.0.1など)、[データベース名]の部分に接続するデータベースの名前(AdventureWorks2017, TestDataBaseなど)を環境に合わせて指定してください。上記の例ではWindows認証で接続するように設定しています。(Integrated Security=True)
Program.cs
以下のコードは自動で生成されるので変更の必要はありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace EntityClassCodeGenerator { static class Program { /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new EntityClassCodeGeneratorForm()); } } } |
プログラムの実行
プロジェクトをビルドしてプログラム(アプリケーション)を実行します。
接続するデータベースにはMicrosoftが公開しているAdventureWorks2017を使用します。
プログラムを起動すると、「スキーマ」コンボボックスのリストアイテムにスキーマの一覧が設定され、リストアイテムの先頭スキーマ(ここではdbo)が選択されます。
選択されたスキーマが所有するテーブルの一覧が「テーブル/ビュー」コンボボックスのリストアイテム設定され、リストアイテムの先頭のテーブル(ここではAWBuildVersion)が選択されます。
エンティティクラスのコードを作成するテーブルまたはビューを選択し、必要なオプションを選んで「作成」ボタンをクリックすると、対象のテーブルまたはビューのエンティティクラスのコードが生成されます。