# 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
```

## 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 框架

圖片來源:[台灣 .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
```

例如,`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 後檢查文字長度:

## 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)。

圖片來源:[認識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.

請確認 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; }
...
}
```