承上題 [報表程式 - 1] 單一觸發點
今天我們稍微把上次的例子做個變化
1. 當報進站事件 ( MoveIn ) => 數量 (Qty) 都要 +1
2. 當報出站事件時 ( MoveOut ) => 數量 (Qty) 都要 -1
但除此之外,其他欄位邏輯都相同
這個例子我會分成四種情境講解
剛好對應到寫報告程式時 最常見的四種型態
這篇是2. 兩事件 (繼承)
完整程式碼請見 https://gitlab.com/jesperlai/Report
主要的變化為
1. Controller.cs不見了 => 共用的邏輯寫在BaseEvent.cs中,各Event相異的邏輯在各Event.cs中
2. Helper裡面的取TriggerPoint的檔案也不見了 => 轉移到各Event.cs中
故Program.cs會變成
using Sample_2.Event;
using Sample_2.Models;
using Sample_2.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sample_2
{
class Program
{
private static BuildEventParam MakeBuildEventParam(string eventName)
{
return new BuildEventParam
{
//為了方便講解 (通常這兩個值會從外面傳進來)---------
STime = DateTime.Parse("2001/1/1"),
ETime = DateTime.Parse("2001/2/1"),
//--------------------------------------------------
EventName = eventName,
};
}
static void Main(string[] args)
{
var result = new List<Report>();
//進站
BaseEvent moveIn = new Event_MoveIn(MakeBuildEventParam("這是一個進站事件"));
result.AddRange(moveIn.Run());
//出站
BaseEvent moveOut = new Event_MoveOut(MakeBuildEventParam("這是一個出站事件"));
result.AddRange(moveOut.Run());
//寫出檔案
RptService myRpt = new RptService();
result = result.OrderBy(q => q.Txn_Dt).ToList(); //最後輸出資料要以過站時間排序
myRpt.GenFile(result, @"D:\sample.csv");
}
}
}
Event資料夾下
BaseEvent.cs
using Sample_2.Extensions;
using Sample_2.Helper;
using Sample_2.Models;
using Sample_2.Utility;
using Sample_2.ViewModels;
using System.Collections.Generic;
namespace Sample_2.Event
{
public abstract class BaseEvent
{
private DataAccessHelper _helper;
protected Repository repo;
protected BuildEventParam builderParam;
public BaseEvent(BuildEventParam param)
{
builderParam = param;
repo = new Repository();
_helper = new DataAccessHelper(repo);
}
public List<Report> Run()
{
var triggerPoint = GetTriggerPoint();
return GetData(triggerPoint);
}
public abstract List<Lot_Txn> GetTriggerPoint();
public virtual List<Report> GetData(List<Lot_Txn> triggerPoints)
{
var dataSet = _helper.ConcreteDataSet(triggerPoints);
var result = new List<Report>();
//我把Trigger Point 觸發點 縮寫成tp
foreach (var tp in triggerPoints)
{
//該回合需用到的資料 我把this round 縮寫成 tRound
var tRound = DataAccessHelper.GetThisRoundData(dataSet, tp);
//Controller 盡量扁平 如果有複雜的運算可以放到 Utility 做
var item = new Report
{
Txn_Dt = tp.Txn_Dt,
Lot_No = tp.Lot_No,
Stage_Id = tp.Stage_Id,
Qty = tp.Qty.Trim(), //有些轉型或是常用的運算 寫成extension會比較易用
Po_No = tRound.So.Po_No,
Order_Qty = tRound.So.Qty,
Sod = DataUtility.GetSod(tRound.So), //假設這個欄位有很複雜的邏輯 放到Utitlity做
Event_Name = builderParam.EventName,
};
result.Add(item);
}
return result;
}
}
}
Event_MoveIn.cs
using Sample_2.Models;
using Sample_2.ViewModels;
using System.Collections.Generic;
namespace Sample_2.Event
{
public class Event_MoveIn : BaseEvent
{
public Event_MoveIn(BuildEventParam param) : base(param)
{
}
public override List<Lot_Txn> GetTriggerPoint()
{
var txns = repo.GetTxn(builderParam.STime, builderParam.ETime, "進站");
return txns;
}
public override List<Report> GetData(List<Lot_Txn> triggerPoints)
{
var result = base.GetData(triggerPoints);
//處理一些該 event 特別不同於 base event 的地方
foreach (var item in result)
{
item.Qty += 1; //隨便舉例 假設進站數量都固定要 + 1
//通常還會有更多更多相異處
//通常還會有更多更多相異處
//通常還會有更多更多相異處
//通常還會有更多更多相異處
}
return result;
}
}
}
Event_MoveOut.cs
using Sample_2.Models;
using Sample_2.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sample_2.Event
{
public class Event_MoveOut : BaseEvent
{
public Event_MoveOut(BuildEventParam param) : base(param)
{
}
public override List<Lot_Txn> GetTriggerPoint()
{
var txns = repo.GetTxn(builderParam.STime, builderParam.ETime, "出站");
return txns;
}
public override List<Report> GetData(List<Lot_Txn> triggerPoints)
{
var result = base.GetData(triggerPoints);
//處理一些該 event 特別不同於 base event 的地方
foreach (var item in result)
{
item.Qty -= 1; //隨便舉例 假設進站數量都固定要 - 1
//通常還會有更多更多相異處
//通常還會有更多更多相異處
//通常還會有更多更多相異處
//通常還會有更多更多相異處
}
return result;
}
}
}
Helper 資料夾下
2_DataAccessHelper.TriggerPoint.cs
using Sample_1.Models;
using Sample_1.ViewModels;
using System.Collections.Generic;
namespace Sample_1.Helper
{
public partial class DataAccessHelper
{
public TriggerPointAndDataSetVM InitializeData()
{
var data = new TriggerPointAndDataSetVM();
data.Tp = GetTriggerPoints();
data.DataSet = ConcreteDataSet(data.Tp);
return data;
}
private List<Lot_Txn> GetTriggerPoints()
{
return _repo.GetTxn(_dataStartTime, _dataEndTime);
}
}
}
其他的程式碼幾乎都是跟單一Event的程式是一樣的