分類: LINQ

提升您公司效率的最佳軟體解決方案 – 磐德國際股份有限公司開啟全新營運效率時代的關鍵

      在現代商業競爭激烈的環境中,提升公司營運效率是永遠不會過時的話題。對於磐德國際股份有限公司來說,這不僅僅是提高效率,更是為客戶提供更優質服務的重要一環。我們自豪地宣布,磐德公司選擇了我們的網智數位-軟體開發,作為他們營運效率提升的關鍵戰略夥伴。

磐德廚藝P.D Kitchen | Taipei

磐德公司的選擇,不僅是對我們系統卓越性能的肯定,更是對我們長期以來在軟體開發和營運優化方面的專業實力的認可。我們致力於提供的不僅是一個ERP管理軟體,更是一個能夠重新定義企業營運方式的解決方案。

網智數位-軟體開發的系統,基於對各行業需求的深刻理解,具有高度靈活性和可擴展性。這個系統不僅僅是一個工具,更是一個能夠優化流程、提高效率、並且自動化重複性工作的全面解決方案。磐德公司選擇我們,就是選擇了一個能夠實現他們營運目標的可靠夥伴。

我們深知,每一個客戶都有其獨特的需求和挑戰。因此,我們的團隊與磐德公司緊密合作,確保系統能夠完美貼合他們的營運模式,為他們量身定制了最佳解決方案。經過一段時間的實施和使用,磐德公司已經開始看到了显著的成效。

我們與磐德公司的合作並不僅僅是一次導入,而是一個長期伙伴關係的開始。我們承諾持續提供最佳的支持和服務,確保他們在營運上的成功與成長。網智數位-軟體開發將繼續與磐德公司攜手,共同探索更多創新、更多效率提升的可能性。

網智數位-軟體開發自豪地成為磐德公司營運效率提升的關鍵,我們將繼續致力於成為每一位客戶最值得信賴的夥伴,幫助他們在競爭激烈的市場中脫穎而出,實現更卓越的成就!


網智數位-開發團隊

一直突破開發技術、累積各種產業知識,而且在出版業、室內設計裝潢業、製造業、機電顧問、貿易、地板、窗簾、窗材、拉門、布料業的商業管理軟體投入有特別的領域知識、也在圖控軟體(圖控軟件)、機械手臂、 Android APP 、iPhone APP、3D列印 開發一直突破再創新,我們也堅持相信好的軟體可以協助企業,不管在管理營運角度、商品創新、決策分析等都絕對是不可缺少的關鍵因素,如果客戶您有任何軟體開發、程式開發委外需求,請聯繫我們讓我們協助您一起討論如何開發一個好的軟體來協助您。

網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:allen@netqna.com
聯繫電話:0920-883-870
公司電話:02-55991310
公司地址(業務營運處):台北市中山區錦州街 25 號 5 樓
skype: netqna
line:netqna
微信:netqna
黃先生 Allen
my_qrcode_1519621481105

Java Script D3 資料過濾教學(軟體設計、軟體開發)

       我在網頁繪圖時,現在常使用 D3 來幫客戶做成統計視覺圖表,但一定會遇到客戶要求在使用者界面上可以進行某些條件的過濾篩選,例如根據勾選或者執行某個按鈕(Button)時,可以顯示或隱藏網頁部分元素圖表,而這樣需求條件,我們就可以利用 Java Script D3 支援的 Filter 函數來實作此需求案例。


案例執行畫面如下

2017-12-04_11-11-28


//完整程式碼如下:

<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8″>
     <title>網智數位 Java Script D3 過濾資料技巧</title>
     <link rel="stylesheet" type="text/css" href="styles.css"/>
     http://d3.js
</head>


<body>



     var data = [ //          {price: 200, category: “捲簾"},
         {price: 300, category: “直立式軌道"},
         {price: 350, category: “木片百葉窗"},
         {price: 500, category: “木竹簾羅馬"},
         {price: 1000, category: “電動軌道"},
         {price: 800, category: “蜂巢簾"},
         {price: 900, category: “百葉窗"},
         {price: 500, category: “壁紙"},
         {price: 300, category: “耐磨地板"},
         {price: 700, category: “衛浴"},
         {price: 400, category: “馬桶"}
     ];


    function render(data, category) {
         d3.select(“body").selectAll(“div.h-bar") //                  .data(data)
             .enter()
             .append(“div")
                 .attr(“class", “h-bar")
             .append(“span");


        d3.select(“body").selectAll(“div.h-bar") //                  .data(data)
             .exit().remove();


        d3.select(“body").selectAll(“div.h-bar") //                  .data(data)
             .attr(“class", “h-bar")
             .style(“width", function (d) {
                 return (d.price) * 0.6 + “px";}
             )
             .select(“span")
                 .text(function (d) {
                     return d.category;
                 });


        d3.select(“body").selectAll(“div.h-bar")
                 .filter(function (d, i) { //                      return d.category == category;
                 })
                 .classed(“selected", true);
     }


    render(data);


    function select(category) {
         render(data, category);
     }


    
         耐磨地板
    
    
         電動軌道
    
    
         壁紙
    
    
         取消選取
    


</body>


</html>


重點程式碼講解:

1. 程式碼註解 A ,我在這邊宣告了 一個 data 變數,它存放了一系列 json 格式的物件,該物件 有 2個屬性 分別為 price(記錄價格)、category(記錄類型)。

    var data = [ // <- 程式碼註解 A
        {price: 200, category: “捲簾"},
        {price: 300, category: “直立式軌道"},
        {price: 350, category: “木片百葉窗"},
        {price: 500, category: “木竹簾羅馬"},
        {price: 1000, category: “電動軌道"},
        {price: 800, category: “蜂巢簾"},
        {price: 900, category: “百葉窗"},
         {price: 500, category: “壁紙"},
        {price: 300, category: “耐磨地板"},
         {price: 700, category: “衛浴"},
         {price: 400, category: “馬桶"}
     ];

2.程式碼註解 B,透過 D3 的選取方式

d3.select(“body").selectAll(“div.h-bar").data(data).enter()

這行程式碼,透將會將 所有數據與 網頁的 <div id=’h-bar’> ,做交集的動作,使得每個數據可以對應各自的 <div id=’h-bar’> 元素。

3.程式碼註解 D,將選取的  <div id=’h-bar’> ,根據 data 的 price 價格 用公式來設定長度,以及透過 text() 來設定文字。

d3.select(“body").selectAll(“div.h-bar") // <- 程式碼註解 D
                 .data(data)
             .attr(“class", “h-bar")
             .style(“width", function (d) {
                 return (d.price) * 0.6 + “px";}
             )
            .select(“span")
                 .text(function (d) {
                     return d.category;
                 });

4.程式碼註解 E,也是最重要的,我根據 d3 支援的 filter()函數,來過濾要選擇的資料。

d3.select(“body").selectAll(“div.h-bar")
                 .filter(function (d, i) { // <- 程式碼註解 E
                     return d.category == category;
                 })
                .classed(“selected", true);

其他參考文章
HTML CSS 動畫教學–【軟體開發(軟件開發)】
繪圖程式-折線圖、區域圖 實作一
產品報告與能源曲線分析系統
利用 JavaScript D3 在網頁動態產生直條圖(軟體開發、軟件開發)
Java Script D3 資料過濾教學(軟體設計、軟體開發)
利用 JavaScript D3 在網頁動態產生直條圖(軟體開發、軟件開發)

網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:
allen@netqna.com
聯繫電話:0920-883-870
公司電話:02-5599-1310
skype: netqna
line:netqna
微信:netqna
黃先生 Allen

在 .Net 透過 Thread 類別撰寫多執行緒多工作業【軟體開發、軟件開發、客製化軟體】

     此篇文章主要是延續上一篇 【C#多工作業與平行處理技術講解】,講解與實作如何在利用強大的 Thread 類別,使用 C# 來撰寫多執行緒多工作業功能。

在 .Net 平台中 Thread 類別位於 System.Threading 命名空間中,此類別封裝了多執行緒許多方法與功能,可以讓我們快速建立新的執行緒,進而在新的執行緒執行所需要的程式碼邏輯,在我們建立一個 Thread 的實例(Instance)時,需要透過一個委派(Delegate)與新建立的 Thread 實例和一個現有的方法(Method)進行綁定,當執行緒(Thread)啟動後,就會立即執行這個綁定的方法。

傳遞給 Thead 的建構子的委派(Delegate)有 2 種,一種是不帶任何參數的委派方法;第二種是可以帶一個 object 參數的委派方法。在我們實體化 Thread 物件後,就可以開始調用 Thread.Start()方法,來啟動執行緒(也會開始執行綁定的方法),而在執行過程隨時可以調用 Thread.Abort()方法,來強制終止執行緒的執行,不過這個 Abort()方法會引發一個 ThreadStateException 例外錯誤。

現在我就帶一個實際範例來是示範如何 用 C# 使用 Thread 類別,建立一個執行緒作業,這邊為了簡單講解觀念,我使用最簡單的 Windows Form 專案來講解。

Step 1. 透過 Visual Studio 2017(舊版本 2015/2013/2012都行啦)新增一個 Windows Form 專案

2017-07-02_23-33-29

Step 2.在 Step 1建立的 Windos  Form 專案後,會產生一個 Form1的界面表單,打開此表單,然後從工具箱拖拉一個 ProgressBar 控制箱到 Form1 畫面,並排好版面。

step2

     Step 3. 從工具箱在拖拉一個 Button 到 Form1 的畫面,並將 name 屬性命名為 btnTread , Text 修改為【Thread 執行緒 啟動】step3

 Step 4. 在 Form1.cs 後置程式碼裡,我撰寫了一個 DoWok() 方法,裡面撰寫了一下邏輯,程式碼如下:

/// <summary>
/// 此方法將會透過委派(Delegate)指定給新的執行緒(Thread)
/// </summary>
private void DoWork()
{
  int p = 0;

  while (p < 100)
  {
    p++;
    Thread.Sleep(100);

    //更新進度表
    this.BeginInvoke(new Action(() =>
    {
       this.progressBar1.Value = p;
    }));
  }

  this.BeginInvoke(new Action(delegate ()
  {
   //再次啟用按鈕狀態
   btnTreadStart.Enabled = true;
   //重設定進度表為 0
   progressBar1.Value = 0;
   //顯示執行緒已完成
   MessageBox.Show(“執行緒已完成。", “執行緒已完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
  }));

}

step4

Step 5. 在 Form1 的 Button 按鈕,雙擊滑鼠 (button1_Click),在button1_Click 事件我撰寫了 核心的 操控 Thread 程式碼

private void button1_Click(object sender, EventArgs e)
{

  //宣告一個 Thread 類別,並將在傳入 Step 4 所宣告的 DoWord 方法
  //待會 Thead 執行時,就會立即執行 DoWord 方法
  Thread newThread = new Thread(DoWork);

  //停用按鈕
  btnTreadStart.Enabled = false;

  //啟用新的執行緒
  newThread.Start();

}

step5

Step 6. Compile 編譯執行(執行F5),就可以看到結果

step 5-1

step 5-2

 

程式碼補充解釋:
因為基於執行緒的安全考量和包含使用者界面完整性,一般而言,系統是限制跨執行緒去更新修改使用者界面,所以在 Step 4 的 DoWokd方法,我透過呼叫 this.BeginInvoke() 方法傳遞一個 委派,使得可以在使用者界面的主執行緒上面進行更新使用者界面的控制箱(ProgressBar1),所以可以看到進度表一直不斷更新。

透過這一篇文章希望可以說明如何利用 Thread 類別來操作多執行作業,後續我還會抽出時間講解不同的非同步多工作業方式,分成不同的文章來一一描述。

 

 

網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:allen@netqna.com
聯繫電話:0920-883-870
公司電話:02-55991310
公司地址(業務營運處):台北市中山區錦州街 25 號 5 樓
skype: netqna
line:netqna
微信:netqna
黃先生 Allen

 

好的管理軟體絕對可以協作企業與店家提升管理績效

     網智數位-軟體開發團隊,累積了超過10年開發中小企業的管理軟體(軟件)委外案,有超過 8 成比例都是完全從無到有,量身訂做去了解客戶的營運流程、現行文件(例如 Excel、Word、PDF)、紙上紙本,大量收集後,跟業主不斷的溝通了解,並給出適當的系統開發建議,目的就是協助客戶從繁雜的作業流程、人工作賬、紙上作業、傳真文件等,開發客戶合適的管理軟體。

image

     上圖就是新竹與台南某廠商客戶,因為長期以來被大量客戶的文件測試報告、檢驗報告,各種客戶所該維護的專案、委託案、以及該專案需派工的檢驗人員、檢驗統計數字、是否需要複查等各種作業模式所困擾,以往光單單人工作業、紙本查詢可能就需要花上人力成本超過5~10天,而現在經過 網智數位-軟體開發團隊,進入分析與建議並開發該作業模式的管理系統軟體(軟件),該軟體可以協助客戶,進行企業的客戶管理(CRM)、以及迅速通知那些專案目前有發生需要追蹤、系統跑出各種統計圖表、歷年的專案報告匯出和匯入,案子的各式圖片管理等,迅速達到委託我們開發軟體的客戶管理績效,所以好的軟體管理系統是可以迅速提升企業的效率與效益。

 

網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:allen@netqna.com
聯繫電話:0920-883-870
skype: netqna
line:netqna
微信:netqna
黃先生 Allen

.NET C# 7 語法 新特性 快速預覽 (軟體開發)

目前最新的 Visual Studio 15 發表的預覽版中,我們可以看出來,微軟決定為眾多的 .NET C# 開發人員,而新增了下列的 C# 7 語法新功能特色 。

元組值類型
.NET 提供了一個元組(Tuple)類型,但具體在 C# 中使用時卻存在著各種各樣的問題。由於元組類型是一個引用類型(Reference),而也因此在一些對於性能相當敏感的程式碼行中,開發者很可能會避免因使用它而造成 GC(Garbage Collection) 的開銷成本。同時,元組類型是不可變的,雖然這使跨線程( Thread) 共享變得更安全,但也意味著每次進行變更都必須分配一個新的對象。

下載

為了應對這一問題,C# 7 將提供一個值類型(Value)的元組。這是一個可變類型,對那些重視性能的程式碼來說,這種方式將更為高效。同時,作為值類型,它在每次進行分配時都會生成一個拷貝,因此幾乎沒有產生多線程(Multi-Thread) 問題的風險。
程式開發人員現在可以透過下列語法創建一個元組:
var result = (6, 20);

你也可以選擇對元組中的值進行命名,這一點並不是必須的,只是讓程式碼具有更好的可讀性。
var result = (count: 6 sum: 20);

你可能會想,“很棒的特性,但我自己也能寫得出來”。但下一個特性才是重頭戲。
多返回值,在類C風格的語言中,要在一個函數中返回兩個值始終是一件麻煩事。你只能選擇將結果封裝成某種結構,或是使用輸出參數。與許多函數式編程語言一樣,C#選擇了第一種方式為你提供這一特性:
(int, int) Tally (IEnumerable<int> list)

可以看到,在這裡使用泛用的元組有一個基本問題:我們將無從得知每個字段的作用。因此,C#選擇通過一個編譯器花招對結果進行命名:
(int Count, int Sum) Tally (IEnumerable<int> list)

我們在此需要強調一點:C#並沒有生成一個新的匿名類型,你所獲得的仍舊是一個元組,但編譯器將假設它的屬性為 Count 和 Sum,而不是 Item1 和 Item2。所以,以下程式碼行的作用都是等價的:

var result = Tally (list);
Console.WriteLine (result.Item1);
Console.WriteLine (result.Count);

請注意一點,我們現在還不具備多賦值語法,如果這種語法最終實現,那麼它的用法可能是這樣的:
(count, sum) = Tally (list);

除了提供簡單的功能性函數之外,多返回值的實用性還體現在非同步的程式碼的編寫上,因為在 async 函數中是不允許使用 out 參數的。
模式匹配:改進的 Switch 語法塊
VB 與函數式程序員對於 C# 抱怨得最多的一點就是 C# 中的 switch 語句功能十分有限。 VB 開發者希望能夠進行範圍匹配,而習慣了F#或 Haskell 的開發者則希望能夠使用分解式的模式匹配。 C#打算同時提供這兩種特性。

在對類型進行模式匹配時,你可以創建一個變量以保存轉型的結果。舉例來說,在對一個 System.Object 使用 switch 語句時,你可以編寫以下程式碼:
case int x:
如果該對像是數值類型,則變量x將得以賦值。否則的話,程序將按從上至下的順序檢查下一個 case 語句塊。如果你想更具體地進行匹配,還可以使用範圍檢查:
case int x when x > 0:
case int y:
在這個示例中,如果該對像是正整數,則x程式碼塊將被執行。如果對像是 0 或負整數,而y程式碼塊將被執行。
如果需要檢查 null 值,則只需使用以下語法:
case null;

模式匹配:分解
目前為止,我們僅僅展示了某種對 VB 中已有的特性所做的增量式改進,而模式匹配真正的強大之處在於分解,它可以將某個對象完全拆開,考慮一下以下語法:
if (person is Professor ​​{Subject is var s, FirstName is “Scott"})
這段程式碼完成了兩件事:
它創建了一個本地變量s,將其賦值為((Professor) person) .Subject。
它執行了一次相等性檢查 ((Professor) person) .FirstName == “Scott"。
如果將其用C# 6 程式碼改寫則是這樣:

var temp = person as Professor;
if (temp != null && temp.F​​irstName == “Scott")
{
    var s = temp.Subject

在最終發布中,我們預計能夠同時看到對 switch 語句塊的這兩種改進。
引用返回對於大數據結構進行引用傳遞比起值傳遞要快得多,因為後者需要對整個結構進行拷貝。與之類似,返回一個大數據結構的引用一樣能夠提升速度。
在類似於C這樣的語言中,可以通過指針返回某個結構的引用。這種方式會帶來一個常見的問題,即指針所指向的內存可能會因為某種原因而已經被回收了。
C#通過使用引用的方式迴避這一問題,引用本身是一個附加了規則的指針。最重要的一條規則是,你不能夠返回某個本地變量的引用。如果你嘗試這樣做,那麼該變量所引用的棧信息在函數返回時就已經變得不可訪問了。

在微軟的展示程式碼中,它所返回的引用指向一個數組中的某個結構。由於它實質上是指向數組中某個元素的指針,因此隨後可以對數組本身進行修改。舉例來說:

var x = ref FirstElement (myArray)
x = 5; //MyArray[0] now equals 5

這一語法的用例是對性能高度敏感的程式碼,在大多數應用中都無需使用這一特性。
二進製字面值(Binary Literals)
此次發布還引入了一個小特性,即二進製字面值。這一語法只是一個簡單的前綴而已,例如 5 可以表示為“0b0101”。這一特性的主要用例是設置基於 flag 的枚舉,以及創建位掩碼(bitmask),以用於與C風格語言的互操作。
本地函數
本地函數是指在另一個函數中所定義的函數。第一眼看來,本地函數似乎只是比匿名函數稍好的一種語法。但它實際上還存在幾個優點:
首先,你無需為其分配一個委託以保存該函數。這不僅減少了內存壓力,同時還允許編譯器對該函數進行內聯操作。
其次,在創建閉包時,也無需為其分配一個對象,因為它能夠直接訪問本地變量。這一點同樣能夠改善性能,因為它也減少了 GC 的壓力。
按照第二條規則推算,你將無法創建一個指向本地函數的委託。這一點對於程式碼的組織其實是一個優點,因為你無需創建獨立的函數,並且將現有函數的狀態作為顯式的參數進行傳遞。
部分類的改進
最後演示的特性是一種處理部分類的新方式。在過去,部分類的應用是基於程式碼生成優先的概念而出現的。所生成的會程式碼將包含一系列部分方法,開發者可以選擇實現這些方法,以調整類的行為。
通過新的“replace”語法,開發者就多了一種新選擇,能夠以最直接的方式編寫程式碼,隨後再引入程式碼生成器,並重寫這些方法。以下將通過一個簡單的示例表現開發者的程式碼編寫方式:
public string FirstName {get; set;}
簡單又清晰,但完全不符合 XAML 風格應用的寫法。因此,程式碼生成器將生成如下程式碼:
private string m_FirstName;
static readonly PropertyChangedEventArgs s_FirstName_EventArgs =new PropertyChangedEventArgs (“FirstName")
 
replace public string FirstName {
    get {
        return m_FirstName;
    }
    set {
        if (m_FirstName == value)
            return;
    m_FirstName = value;
    PropertyChanged?.Invoke (this, m_FirstName_EventArg);
}

通過“replace”關鍵字,所生成的程式碼將直接替換手寫的程式碼,添加所缺失的功能。在這個示例中,我們甚至還能夠處理一些開發者經常會忽略的麻煩的部分,例如對 EventArgs 對象進行緩存。
雖然這個官方示例僅用於屬性變更通知,但這一技術還可用於各種“面向切面編程(AOP)”的場景,例如在程式碼中的日誌記錄、安全檢查、參數校驗以及其他各種繁瑣的樣板式程式碼。

 

網智數位-軟體開發(軟件開發)
針對各特殊產業都可以量身定做符合貴公司的需求,別人無法克服的就是我們的挑戰
業務合作、軟體委外開發
業務窗口:allen@netqna.com
聯繫行動號碼:0920-883-870
黃先生 Allen

Entity Framework 實戰 – 多對多自我關聯 Many to Many , Self Referencing 模型實作 (二)

此篇文是 Entity Framework 實戰 – 多對多自我關聯 Many to Many , Self Referencing 模型實作 (一)的續篇 , 當我們把基本模型 Product Class 建立好後,我們開始實作一個繼承 DbContext 的子類別,在這邊你可以把 DbContext 當做是資料庫的層次意義角度來看待

新增一個Class 名為 ProductContext.cs

image

然後按【新增】按鈕,並在 ProductContext 宣示繼承 DbContext 類別,如以下程式碼

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Data.Entity;
  4: using System.Linq;
  5: using System.Text;
  6: using System.Threading.Tasks;
  7: 
  8: namespace EF6_ManyToManyAndSelf
  9: {
 10:     public class ProductContext : DbContext
 11:     {
 12: 
 13:     }
 14: }

接著加入 DbSet<Product> 的宣告,用於表示 存放著 Product Table(Class)的集合清單

public DbSet<Product> Products;

然後為了完成透過 Product 本身的 Class 來完成 多對多自身關聯,需要 override OnModelCreating Method , 程式碼如下

   1:   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   2:          {
   3:              base.OnModelCreating(modelBuilder);
   4:   
   5:              modelBuilder.Entity<Product>()
   6:                          .HasMany(p => p.RelatedProducts)
   7:                          .WithMany(p => p.AboveProducts)
   8:                          .Map(m =>
   9:                                    {
  10:                                        m.MapLeftKey("ProductID");
  11:                                        m.MapRightKey("RelatedProductID");
  12:                                        m.ToTable("RelatedProduct");
  13:                                    }
  14:                          );
  15:          }

到這邊基本上已經完成 EntityFramework 的宣告….

然後讓我們在前端界面使用我們實作好的 ProductContext ,來看看如何使用….程式碼如下

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Threading.Tasks;
   6:   
   7:  namespace EF6_ManyToManyAndSelf
   8:  {
   9:      class Program
  10:      {
  11:          static void Main(string[] args)
  12:          {
  13:              using (var context = new ProductContext())
  14:              {
  15:                  var product1 = new Product { ProductName = "美容業零售管理系統", Price = 59888M };
  16:                  var product2 = new Product { ProductName = "窗簾業ERP系統", Price = 3500000M };
  17:                  var product3 = new Product { ProductName = "玩具製造業ERP系統", Price = 6700000M };
  18:                  product2.RelatedProducts.Add(product3);
  19:                  product1.RelatedProducts.Add(product2);
  20:                  context.Products.Add(product1);
  21:                  context.SaveChanges();
  22:              }
  23:              using (var context = new ProductContext())
  24:              {
  25:                  var product2 = context.Products.First(p => p.ProductName == "窗簾業ERP系統");
  26:                  Console.WriteLine("Product: {0} ... {1}", product2.ProductName, product2.Price.ToString("C"));
  27:                  Console.WriteLine("Related Products");
  28:                  foreach (var prod in product2.RelatedProducts)
  29:                  {
  30:                      Console.WriteLine("\t{0} ... {1}", prod.ProductName, prod.Price.ToString("C"));
  31:                  }
  32:                  foreach (var prod in product2.AboveProducts)
  33:                  {
  34:                      Console.WriteLine("\t{0} ... {1}", prod.ProductName, prod.Price.ToString("C"));
  35:                  }
  36:              }
  37:   
  38:              Console.ReadKey();
  39:          }
  40:      }
  41:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

執行結果為
 
image
 
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

網智數位-軟體開發(軟件開發)
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }