# ASP.NET MVC with IBM Data Server EF 6 Provider for Entity Framework 6 ###### tags: `ASP.NET MVC` `DB2` `Entity Framework` `EF` `Sequence contains no matching element` `ORM` --- [TOC] --- ## Prerequisite > * Visual Studio 2013 > * Entity Framework 6 Tools for Visual Studio 2012 & 2013 > * .NET Framework 4.7.2 > * NuGet Package Manager for Visual Studio 2013 > * IBM Data Server Client V10.5 > * IBM Database Add-Ins for Visual Studio V10.5 ### NuGet 請在 `C:\ProgramData\NuGet\Config\VisualStudio\12.0` 新增 `NuGet.Config` 檔案,其內容為: ```xml <?xml version="1.0" encoding="utf-8"?> <configuration> <config> <add key="repositorypath" value="C:\ProgramData\NuGet\packages" /> </config> <packageSources> <add key="Private NuGet Packages" value="\\172.27.10.99\cim\DP0510\CF\03-WebProject\private_nuget_packages" /> </packageSources> </configuration> ``` 新增完成後,開啟 Visual Studio,確認 **套件來源**;工具(T) > NuGet 封裝管理員(N) > 套件管理員設定\(P\) > 套件來源。 * Available ++p++ackage sources ``` Name: nuget.org Source: https://www.nuget.org/api/v2/ ``` * ++M++achine-wide packages sources ``` Name: Private NuGet Packages Source: \\172.27.10.99\cim\DP0510\CF\03-WebProject\private_nuget_packages ``` ![](https://i.imgur.com/yX0yjJu.png) ## Visual Basic .NET and Web API See [Visual Basic .NET and Web API](/gwtJlLh9RGKA1uj4R11ppw) ## Getting Started with ASP.NET MVC 5 See [ASP.NET MVC Tutorials](https://www.tutorialsteacher.com/mvc/asp.net-mvc-tutorials) and [Getting Started with ASP.NET MVC 5 | Microsoft Docs](https://docs.microsoft.com/zh-tw/aspnet/mvc/overview/getting-started/introduction/) ### MVC 框架 ![](https://i.imgur.com/xktQMN1.png) 圖片來源:[台灣 .NET 技術愛好者俱樂部](https://www.facebook.com/groups/DotNetUserGroupTaiwan/permalink/2531689860457450/) > 前後端和框架無關 > [name=陳傳興] ## Models ### Context #### 繼承自 `DB2Context<[DB]Context>` 新增 `[DB]Context` 後,其中 `[DB]` 是您新增的資料庫的名稱,請把 `Line 1` 繼承自 `DbContext` 的 Class,修改為繼承自 `DB2Context<[DB]Context>` 的 `Line 4`。 例如,把 `DbContext` 改成 `DB2Context<CFPPPTContext>`: ```csharp= //public partial class CFPPPTContext : DbContext //{ } public partial class CFPPPTContext : DB2Context<CFPPPTContext> { } ``` ### Model #### 取消 `[Column(TypeName = "integer|character|...|date")]` 註解 `[Column(TypeName = "integer|character|...|date")]`,請使用 **尋找和取代** <kbd>Ctrl + H</kbd>,以及 **使用規則運算式**。 ``` Search: (^ *)(\[Column\((((Order *= *\d+)|\w+ *= *["\w\d]+)(, *)*)+\)\])\r\n Replace: $1//$2\r\n$1[Column($5)]\r\n ``` ![](https://i.imgur.com/szwF0m7.png) 例如,`BCARRIER` 取代後結果為: ```csharp [Table("PPT.BCARRIER")] public partial class BCARRIER { [Key] //[Column(TypeName = "character")] [Column()] [StringLength(10)] public string CRR_ID { get; set; } //[Column(TypeName = "character")] [Column()] [Required] [StringLength(3)] public string CRR_OWN { get; set; } //[Column(TypeName = "character")] [Column()] [Required] [StringLength(4)] public string CRR_STAT { get; set; } ... } ``` #### 定義 Model 內的屬性 `Attribute` 若有需要定義 Model 內的屬性的 `Attribute`,請另外新增一個 `[Model]Metadata.cs`;避免重新 Scaffolding 後會在覆蓋掉到原來的 Model。 > * `[Model]Metadata.cs` > * `public partial class [Model]` > * `[MetadataType(typeof([Model]Metadata))]` 例如,`BCARRIER.cs` 要新增 `[DisplayName()]` 顯示名稱,以及新增 `[StringLength()]` 的資料驗證。 首先,新增 `BCARRIERMetadata.cs`,並加上 `[DisplayName()]` 在需要顯示名稱的屬性,以及 `[StringLength()]` 的資料驗證: ```csharp public class BCARRIERMetadata { [DisplayName("Cassette ID")] [StringLength(10, ErrorMessage = "Cassette ID 的文字長度請小於 10。")] public string CRR_ID { get; set; } [DisplayName("Equipment ID")] public string POSITION { get; set; } [DisplayName("Port ID")] public string PORT_ID { get; set; } } ``` 接著,在 `BCARRIERMetadata.cs` 新增 `BCARRIER` 的 **Partial Classes**,並加上 `[MetadataType(typeof(BCARRIERMetadata))]`,把 `BCARRIER` Model 關聯到 `BCARRIERMetadata`,如下 `Line 1 ~ 3` 的程式碼。 ```csharp= [MetadataType(typeof(BCARRIERMetadata))] public partial class BCARRIER { } public class BCARRIERMetadata { [DisplayName("Cassette ID")] [StringLength(10, ErrorMessage = "Cassette ID 的文字長度請小於 10。")] public string CRR_ID { get; set; } [DisplayName("Equipment ID")] public string POSITION { get; set; } [DisplayName("Port ID")] public string PORT_ID { get; set; } } ``` 在頁面中,可以看 Cassette ID 以及按下 Submit 後檢查文字長度: ![](https://i.imgur.com/aoaFUoo.png) ## Controllers ### Action Methods {%hackmd GcXhXeoFSiqITGON247zCw %} ## Views ### Raozor 在 View (`*.cshtml`) 中使用 Razor 語法,可以寫 HTML 和在 Server-side 的 C#。 詳細說明,請參考 [ASP.NET Razor Syntax](https://www.tutorialsteacher.com/mvc/razor-syntax)。 ### Passing Data to Views {%hackmd vj7wzkuhRtivacag2vgNPA %} ### Razor Viw Engine 例如,下面的 `Create.cshtml`,經過 Razor View Engine 編譯成 HTML: ```htmlembedded= @using (Html.BeginForm("Create", "BCARRIERs", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>BCARRIER</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.CRR_ID, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.CRR_ID, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.CRR_ID, "", new { @class = "text-danger" }) </div> </div> ... </div> } ``` ```htmlembedded= <form action="/BCARRIERs/Create" enctype="multipart/form-data" method="post"> <input name="__RequestVerificationToken" type="hidden" value="E8dRaFC_nrUQSt6Dx5Ul51_oOnuwvYhCDwC05wNk4c0YIVJF_SjgaBae_9BM0JN509KTJ-S5zoiELetmrWdDJk1bhK5zGI2XqIp_d8U7VOk1"> <div class="form-horizontal"> <h4>BCARRIER</h4> <hr> <div class="form-group"> <label class="control-label col-md-2" for="CRR_ID">Cassette ID</label> <div class="col-md-10"> <input class="form-control text-box single-line" data-val="true" data-val-length="Cassette ID 的文字長度請小於 10。" data-val-length-max="10" id="CRR_ID" name="CRR_ID" type="text" value=""> <span class="field-validation-valid text-danger" data-valmsg-for="CRR_ID" data-valmsg-replace="true"></span> </div> </div> ... </div> </form> ``` ### HTMLHelper 詳細說明,請參考 [HTML Helpers in ASP.Net MVC](https://www.tutorialsteacher.com/mvc/html-helpers)。 ![](https://i.imgur.com/GcBlrBw.png) 圖片來源:[認識View - Helper - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10160299) * `@Html.BeginForm()` ```htmlembedded @using (Html.BeginForm("Create", "BCARRIERs", FormMethod.Post, new { enctype = "multipart/form-data" }) { } <form action="/BCARRIERs/Create" enctype="multipart/form-data" method="post"> ``` * `@Html.LabelFor()` ```htmlembedded @Html.LabelFor(model => model.CRR_ID, htmlAttributes: new { @class = "control-label col-md-2" }) <label class="control-label col-md-2" for="CRR_ID">Cassette ID</label> ``` * `@Html.EditorFor()` ```htmlembedded @Html.EditorFor(model => model.CRR_ID, new { htmlAttributes = new { @class = "form-control" } }) <input class="form-control text-box single-line" data-val="true" data-val-length="Cassette ID 的文字長度請小於 10。" data-val-length-max="10" id="CRR_ID" name="CRR_ID" type="text" value=""> ``` ## Troubleshooting ### 新增 Controller #### Sequence contains no matching element. ![](https://i.imgur.com/aZadanb.png) 請確認 Context 內的所有 Models 內有沒有 `[Column(TypeName = "integer|character|...|date")]`,若有,取代為 `[Column()]`。 例如,`HCFRPT3Context` 中有 7 個 Models,所有的 Models 都要像 `MANAGE_MASK` 一樣,把 `Line 12` 改成 `Line 13`: ```csharp= public partial class HCFRPT3Context : DB2Context<HCFRPT3Context> { public HCFRPT3Context() : base("name=HCFRPT3Context") { } public virtual DbSet<MANAGE_MASK> MANAGE_MASKs { get; set; } public virtual DbSet<MANAGE_MASK_SET> MANAGE_MASK_SETs { get; set; } public virtual DbSet<HBPRDCT> HBPRDCTs { get; set; } public virtual DbSet<HBRETICLE> HBRETICLEs { get; set; } public virtual DbSet<PPID_FBC0000> PPID_FBC0000s { get; set; } public virtual DbSet<PPID_FBM0000> PPID_FBM0000s { get; set; } public virtual DbSet<PPID_FOC0000> PPID_FOC0000s { get; set; } ... } ``` ```csharp= [Table("CFWEB.MANAGE_MASK")] public partial class MANAGE_MASK { [Key] [StringLength(20)] public string MASK_ID { get; set; } [Required] [StringLength(20)] public string MNAME { get; set; } //[Column(TypeName = "integer")] [Column()] public int SHOT { get; set; } ... } ```