2018年11月22日 星期四

Database Project 結構描述比較時出現 目標無法使用 | SQL Schema Comparison Error “Target is unavailable”

markdown

# 說明
進行DB schema更新時使用database project的結構描述比較
但按下比較時狀態列出現目標無法使用的錯誤訊息
重開vs2017也沒用

# 解法
參考這裡
https://stackoverflow.com/questions/37463279/sql-schema-comparison-error-target-is-unavailable

將連線字串的帳號名稱格式改為加上伺服器名稱
**username@servername**
就成功了

2018年9月7日 星期五

Azure Function Timer Trigger Cron 運算式 如何確定寫好的式子是想要的

markdown

最近在設定Azure Function的定時觸發類型程式的CRON運算式
寫好之後不太確定自己寫得到底對不對
研究了一下後有兩個做法

1. 本地偵錯模式
2. 用工具網站https://crontab.guru/

# 本地偵錯模式

本地執行後Console視窗上會寫目前執行中的Timer Trigger Function有哪些
以及列出這個Function之後會執行的五個時間點給你看,如圖:



# crontab guru

網站網址:https://crontab.guru/

Azure Function的Timer Trigger文件部分其實就有寫,時間運算式使用的是NCronTab 這個LIB來處理,所以就往「CRON運算式 確認」的方向去google,然後就找到這個網站,
雖然他比Azure少一層秒數的表達式,但也是可以提供一個參考,
直接把打好的表達式輸入進去,就可以看到你寫的會以怎樣的週期去執行:


不知道有沒有人做給Azure Function 用的版本,不然還是比較方便

2018年8月9日 星期四

找出某個namespace下所有類別裡面有哪些類別的哪些屬性不是單純的get set | find out class that have not simple getter setter property in specific name space

markdown

# 需求描述
因為要做重構,需要找出有哪些邏輯是藏在DTO裡面的,
但DTO類別檔又很多,不想一個個找
所以就想寫個console程式來撈

# 做法
首先把要撈的DLL跟他相依的DLL都複製到要執行的排程執行檔輸出資料夾(通常是bin\debug)

以下程式碼:
```
public class Worker { public void DoWork() { System.Reflection.Assembly service = Assembly.LoadFile(@"<你要找的namespace所在的dll的絕對路徑>.dll"); Type[] typelist = service.GetTypes(); var nameHaveDtoTypes = typelist.Where(x => x.Name.ToUpper().EndsWith("DTO"));//你的類別名稱的特徵,例如找DTO就結尾是DTO foreach (var typeitem in nameHaveDtoTypes) { if(typeitem.GetProperties().Any(prop=> !MightBeCouldBeMaybeAutoGeneratedInstanceProperty(prop))) { foreach (var prop in typeitem.GetProperties().Where(prop => !MightBeCouldBeMaybeAutoGeneratedInstanceProperty(prop))) { //印到畫面跟輸出視窗 Console.WriteLine($"{typeitem.Name},{prop.Name}"); System.Diagnostics.Debug.WriteLine($"{typeitem.Name},{prop.Name}"); } } } } public bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty(PropertyInfo info) { bool mightBe = info.GetGetMethod() .GetCustomAttributes( typeof(CompilerGeneratedAttribute), true ) .Any(); if (!mightBe) { return false; } bool maybe = info.DeclaringType .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .Where(f => f.Name.Contains(info.Name)) .Where(f => f.Name.Contains("BackingField")) .Where( f => f.GetCustomAttributes( typeof(CompilerGeneratedAttribute), true ).Any() ) .Any(); return maybe; } } ```

參考:
1.LINE群大神指點關鍵字**CompilerGeneratedAttribute**
這個是指在編譯成DLL時,單純getter setter的屬性上面會有這個tag
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.compilergeneratedattribute.aspx

2.How to find out if a property is an auto-implemented property with reflection?
https://stackoverflow.com/questions/2210309/how-to-find-out-if-a-property-is-an-auto-implemented-property-with-reflection?lq=1


2018年7月10日 星期二

GIT常用指令筆記

markdown

最近版控系統完全轉到git,但新手上路,很多指令還不是很熟,
所以寫一篇筆記方便查找

`git clone <target> [<folder name>]`
抓下目標到本地(執行位置),可指定新資料夾名稱

`git add .`
加入目前所有檔案到暫存變更

`git commit [-m <message>]`
簽入暫存變更帶上簽入訊息

`git merge <branch name> --no-ff  `
做merge但不會fast forword

`git log --oneline --graph [-(數字)]`
印出線圖 數字可限制印出幾個簽入內的

2018年5月22日 星期二

Kendo UI MVVM 自訂Validator規則的問題 | Kendo UI MVVM custom required Validator problem

markdown

# 情境

一個Grid,裡面的row是template,
按鈕除了編輯刪除,其他按鈕案出來的視窗也是template,
在template裡面還有套template,然後都是MVVM去設定事件,
在最尾端的一個表單,要做表單驗證,
有一個欄位是radio button,多選一,當選到某值時另一文字輸入框欄位就變必填

# 問題

如何在MVVM的model中套用這個特定的required驗證

# 解題過程

我原本找到去擴充model binding的binder方法的方向
https://stackoverflow.com/questions/15945755/set-tag-attribute-based-on-variable-value-with-kendo-binding/15947852#15947852
但他要做一個html元件的跟一個widget的,名字還有邏輯,沒搞太懂;

後來轉向套用validator在表單上,雖然不太MVVM,但是可解的方法,
可是這個必填欄位不知為何在執行驗證時會跳
`n[t].call is not a function`
錯誤,後來發現 **不能把validator用的物件放在你的MVVM ViewModel**,
他在執行遍歷驗證時會抓到observable的一些屬性但無法辨識(例如`_events`)然後就跳那個錯誤,
我本來以為MVVM就是你用到的東西都塞MODEL裡就對了,不過這個情境應該不是這樣放...
再來是自訂驗證規則名稱的雷,
我原本取名`PayAccountRequired`,結果竟然讓input不是required也套上required屬性,整個鬼打牆找了很久,後來把規則名稱改成`PayAccountRule`,竟然就正常了....

從來沒想到這個驗證會讓我卡好幾個小時....

完成的範例
http://jsfiddle.net/o8ym26jj/2/

2018年5月14日 星期一

本機開發 IIS Express的虛擬目錄失效的問題 | IIS Express virtual directory setting not work

markdown

情境:
本來寫好一個上傳檔案功能,在本機開發的時候有設定虛擬路徑,檔案在
`%USERPROFILE%\documents\IISExpress\config\applicationHost.config`
結果最近在側的時候發現怎麼metadata都抓不到了,明明沒有改東西

解法
後來debug了半天發現我的檔案存放路徑不對,
就覺得是虛擬路徑失效的問題,又繼續查,
發現,其實因為中間我的IDE從vs 2013換到vs2015,
結果vs2015好像有個問題就是他不吃上面路徑的設定擋了,
新的設定檔在專案資料夾內的`.vs`資料夾(是隱藏資料夾)裡的`applicationHost.config`
在同樣的區段去新增虛擬路徑就好了

REF: https://forums.asp.net/t/2067764.aspx?VS2015+IIS+Express+cannot+create+virtual+directories

2018年4月9日 星期一

Kendo UI Grid 摺疊明細裡面再一個Grid 的抓法 | How to get Kendo UI Grid with children detail's grid

markdown

#背景
同事在寫的應用:一個GRID裡面有子GRID
資料在展開master row時才會去抓
但不知道怎麼抓

#解法
我第一個想法是在master grid展開前先記住外面row的uid,
再用uid反推index,再用index去抓到row,再抓到裡面的grid,但很麻煩;

他研究很久後發現在master grid 的detailInit事件做detail grid宣告,
detail grid裡的databound事件
可以用
```
$(this.element[0]).data("kendoGrid"); ```
來抓到裡面的grid,簡單明瞭


2018年3月14日 星期三

SQLServer 找表格所有欄位 欄位型態 欄位備註 | SQLServer query table column type and comment

markdown

```
SELECT c.name '欄位名稱', ep.value AS '欄位備註', t.Name '欄位型態', c.max_length '最大byte', c.precision '總位數', c.scale '小數位數', c.is_nullable '是否可為空', ISNULL(i.is_primary_key, 0) '是否是PK' FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id INNER JOIN sys.objects ON sys.objects.object_id = c.object_id LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id OUTER APPLY fn_listextendedproperty(default, 'SCHEMA', schema_name(sys.objects.schema_id), 'TABLE', sys.objects.name, 'COLUMN', c.name) ep WHERE c.object_id = OBJECT_ID('your table name') ```

ref:
https://stackoverflow.com/questions/2418527/sql-server-query-to-get-the-list-of-columns-in-a-table-along-with-data-types-no
https://devio.wordpress.com/2009/08/19/retrieving-table-and-column-descriptions-in-sql-server/

IIS 安裝Windows 驗證功能 需要重開機嗎? | Does IIS after install Windows authentication function, need restart?

不用

NO

因為要在正式機操作,安全起見才去問&本機測測看....

2018年3月13日 星期二

SQL Server 無法在 date 上呼叫方法

markdown

#背景

我原本有個view
在伺服器1 資料庫A  (1-A)
跨到伺服器1 資料庫B (1-B)

現在這個view移到 伺服器2 資料庫A (2-A) 跨到1-B
建好1到2的db link後
在ssms更新view的sql並執行,出現一個錯誤訊息:
無法在date上呼叫方法

SQL語法直接按新增查詢是可以跑出來結果,
但在SSMS VIEW的語法設計中執行就會出現這個錯誤

#解法

先在GOOGLE找到MSDN上的SQL SERVER錯誤訊息代碼表
https://technet.microsoft.com/zh-tw/library/cc645611(v=sql.105).aspx
然後切成英文,找到關鍵字Cannot Call Methods on
重新搜尋 就找到stackoverflow的討論串
https://stackoverflow.com/questions/16180347/sql-server-cannot-call-methods-on-date

原來是ssms的bug

後來用語法
alter view [view name] as [sql command] 就成功更新了

2018年3月2日 星期五

微軟正黑體font-weight看不出粗細問題


如圖,可以看出並沒有什麼多層粗細,只有普通跟粗體兩種

解決方法:

找有提供粗細字型的字體系列,如思源黑體,用字體切換的方式來達到粗細分明


2018年2月5日 星期一

LUIS訓練筆記

markdown

之前訓練過的筆記,只記在trello,也順便貼過來

筆記

Utterances 話語

話語就是你應用程式期望會收到並想要解釋的使用者查詢語句
增加話語來訓練LUIS讓他懂類似的語句

Intent 意圖

意圖就是動機或者有預期的行動
有個盲點就是有話語通常有意圖
但不一定能從話語中找出實體
這是過去我一直卡住的地方
所以訓練才會卡卡的
應該要把意圖與實體分開看

Entities 實體

實體就是在你應用程式領域中關鍵的資料
例如 關鍵字 日期 班機號碼 天數
例如一個請假功能 輸入
我想在下周三請兩小時的假
透過意圖訓練可以辨識出請假的意圖
但在語句中抓出的實體應該為下周三兩小時

2018年2月2日 星期五

SQL Server 民國日期時間 數字轉datetime | SQL Server Taiwan Calander date and time number to datetime

markdown ``` --原始欄位: --民國年數字date_number,時間數字time_number --(ex:971201,6) --將民國數字轉西元字串 select cast(970101+19110000 as varchar(8)) --output:20080101 --將西元字串轉YYYY-MM-DD字串 select SUBSTRING(cast(970101+19110000 as varchar(8)),1,4)+'-' +SUBSTRING(cast(970101+19110000 as varchar(8)),5,2)+'-' +SUBSTRING(cast(970101+19110000 as varchar(8)),7,2) --output:2008-01-01 --將時分數字PAD成時分秒,在零點時可能只有個位數 如 00:06 =6 select REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') --output:000006 --將補齊的時分秒轉為HH:MM:SS字串 select substring(REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') ,1,2)+':' +substring(REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') ,3,2)+':' +substring(REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') ,5,2) --output:00:00:06 --將時間字串與時分秒字串轉為DATETIME select convert(datetime, SUBSTRING(cast(970101+19110000 as varchar(8)),1,4)+'-' +SUBSTRING(cast(970101+19110000 as varchar(8)),5,2)+'-' +SUBSTRING(cast(970101+19110000 as varchar(8)),7,2) +' ' +substring(REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') ,1,2)+':' +substring(REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') ,3,2)+':' +substring(REPLACE(STR(cast(6 as varchar(6)), 6), SPACE(1), '0') ,5,2) ,121) --output:2008-01-01 00:00:06.000 ```

2018年1月25日 星期四

Kendo UI Grid Filter DatePicker 過濾時分秒 | Kendo UI Grid Filter DatePicker truncate time

markdown

#背景
當grid使用server端做分頁排序篩選時,查詢的邏輯就是靠`ToDataSourceResult`來控制,
所以改不了內容在幹嘛,
當前端Grid需要篩選某日期欄位,該欄位又有時分秒,且使用者不想設定秒數時,
預設的時間篩選欄位只會傳入年月日到後端,時分秒為零,
但這樣在做小於等於或者等於的查詢時就會遇到時分秒不相同而查不到資料的問題,
如果是自己做api,這種小地方可以調整用`System.Data.Entity.DbFunctions.TruncateTime()`來過濾時間,但用Telerik的類別處理時就不行了,

後來查到官方的解法如連結
https://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/filtering/filter-by-date
大致上就是說要在filter menu初始化時,複寫套用的按鈕的事件,
例如原本設"等於"條件時,只會傳入一個邏輯就是相等一個日期時間值,
我們要調整為兩個邏輯,
用大於等於當天的零點零分零秒與 小於等於當天的23點59分59秒兩個條件傳入後端,
這樣就可以避免對不上時間的問題了

```
filterMenuInit: function (e) { //當日期條件設定為小於/等於時 只會傳入年月日 不會傳入時分秒 //但這樣會撈不到當天0點之後的資料 所以要幫他加到23:59:59來方便處理 //(因為沒辦法調整語法為trunc time) var menu = $(e.container); if (e.field === "ColumnDateTime") { var firstDropDown = $('[data-bind="value: filters[0].operator"]').data('kendoDropDownList'); menu.find('button[type="submit"]').click(function (ev) { if (firstDropDown.value() === 'eq') { ev.preventDefault(); var selectedDate = menu.find('[data-role="datepicker"]').first().data('kendoDatePicker').value(); if (!selectedDate) { $(ev.target).closest('[data-role="popup"]').data('kendoPopup').close(); return; } var startOfFilterDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate()); var endOfFilterDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), 23, 59, 59); var filter = { logic: "and", filters: [ { field: "ColumnDateTime", operator: "gte", value: startOfFilterDate }, { field: "ColumnDateTime", operator: "lte", value: endOfFilterDate } ] }; e.sender.dataSource.filter(filter); $(ev.target).closest('[data-role="popup"]').data('kendoPopup').close(); return; } else if (firstDropDown.value() === 'le') { ev.preventDefault(); var selectedDate = menu.find('[data-role="datepicker"]').first().data('kendoDatePicker').value(); if (!selectedDate) { $(ev.target).closest('[data-role="popup"]').data('kendoPopup').close(); return; } var endOfFilterDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), 23, 59, 59); var filter = { logic: "and", filters: [ { field: "ColumnDateTime", operator: "lte", value: endOfFilterDate } ] }; e.sender.dataSource.filter(filter); $(ev.target).closest('[data-role="popup"]').data('kendoPopup').close(); return; } }); } }, ```