讯光科技
Server元件
  • InfoCommand
  • AutoNumber
  • LogIn
  • UpdateComponent
  • Server偵錯
  • Server其他問題

InfoCommand

當前位置:首頁>常見問答>Server元件


用精靈在做出的Server端dll,如何在讀取資料時能有排序或條件篩選功能,SQL語句封裝在哪里呢? 說明如下: (1).資料(SQL語句)的封裝在Server Module中的InfoCommand控件中。 (2).排序可以寫在InfoCommand中,如直接寫Order By,但不可由User變更,或是在Client端使用InfoBidingSource.Sort()方式來排序。 (3).如要使用動態條件,可以使用InfoDataSet.SetWhere()的方式來動態改變SQL的Where語句。
使用存儲過程提取大量數據,在Client客戶端介面執行發生超時的錯誤, 請問應該如何解決? InfoCommand以Stored Procedure中去取資料時,如果需處理很久,則會發生超時的現象,可以在InfoCommand的CommandTimeOut屬性中來設置超時時間。
如果Table中有使用uid的欄位,則在資料存檔時出現[資料行]uid不屬於某個TABLE的錯誤, 如何解決? 1)請檢查:在UpdateComp的FieldAttrs內不應該有UID這個欄位,如果有,請刪除。 2)在InfoCommand中,是否有select uid欄位進去,如果沒有,請加進去。因為在存檔的時候,程式去取得SchemaTable的時候會自動把資料庫中的Key欄位也一同取下來,而程式去取異動行的時候只取到了其他欄位,所以在匹配欄位的時候就會發生錯誤。

AutoNumber

當前位置:首頁>常見問答>Server元件


如何讓AutoNum保存後得到的新流水號直接顯示在頁面上? 自動編號的同步部分有3個地方需要註意: 1. UpdateComp的ServerModify要設為true。 2. InfoBidingSource的AutoApply要設為true。 3. InfoDataSet的ServerModify要設為true,如果是Web則須設定WebDataSet的ServerModify要設定為True。
AutoNumber如何對態抓取User輸入欄位來自動編號? 可有Sample? AutoNumber的GetFixed屬性可以做到,如我們設為MyGetFixed(),表示此自動編號的前置內容由MyGetFixed()函數動態設定。MyGetFixed()的寫法如下: public String MyGetFixed() { //取得PurchaseDate的當前值 object obj = (DateTime)ucMaster.GetFieldCurrentValue("PurchaseDate"); //先定義一個當天日期,以保證既便user沒有輸入該欄位值時用當天日期來編號 DateTime dateTime = DateTime.Today; //判斷user是否輸入資料,如果有,則將其轉換為DateTime類型 if (obj.ToString() != "") { dateTime = (DateTime)obj; } //將這一日期轉換成6位的字串,用來編號 string sFixed = "P" + string.Format("{0:yyMMdd}", dateTime); return sFixed; }

LogIn

當前位置:首頁>常見問答>Server元件


LogInfo元件要如何設置使用? LogInfo元件是專門用來配合UpdateComp所發生的資料新增/更改/刪除所做的紀錄,設定的方式如下: 1.您需要先對某個需要記錄Log的UpdateComp設定其LogInfo屬性,這樣可以使UpdateComp與LogInfo關聯起來。 2. 然後再設定LogInfo元件的各屬性:LogTableName,LogIDField,MarkField,ModifierField,ModifyDateField,以及SrcFieldNames。 其中LogTableName是資料庫中另行建立的紀錄表,需要先設定,就是代表記錄Log的Table名稱,?了能記錄下UpdateComp的異動時間、狀態以及異動者User代碼,必須在此LogTable上加開Log_DateTime ,Log_State,Log_User以及自動遞增欄位log_Id等四個欄位,分別定義於LogIDField、MarkField、ModifierField、ModifyDateField等,代表可以自由設定此四個欄位的名稱。最後SrcFieldName則是設定UpdateComp的資料表中,哪些Field需要做記錄,被選擇的欄位,在LogTalbe中也一定要有相對的欄位名稱。

UpdateComponent

當前位置:首頁>常見問答>Server元件


UpdateComponent的BeforeDelete如何取消刪除? 兩種方法,請參考: 1)如果您是要判斷哪些資料可以刪除哪些不可以,您可以在Client端的BeforeCommand事件中處理,比較簡單。 2)如果是必須要在Server處理的,您需要BeforeDelete事件中寫: if (Convert.Toint16(UpdateComp1.GetFieldOldValue("Qty"))<=0) // 條件成立的話 { throw new Exception("yourMessage"); //拋出異常與訊息 } 然後需要在Client的InfoDataSet的ApplyError事件中接收: if (e.Exception.InnerException.Message == "yourMessage") { MessageBox.Show("yourMessage"); //可以自行改變訊息 e.Cancel = true; //讓系統知道後端有錯誤 }
如何在UpdateComp中去決定存入資料庫的內容值? 在UpdateComp的處理事件中(如BeforeInsert/BeforeModify等),如果需要去決定欄位的內容值,可以使用UpdateComp.SetFieldValue(FieldName,Value)方式來設定,但是SetFieldValue()的欄位對象必須是在InfoCommand存在的欄位,否則會發生錯誤,以下是自動決定更改的使用者與時間的範例: private void ucOrders_BeforeModify(object sender, UpdateComponentBeforeModifyEventArgs e) { ucOrders.SetFieldValue("UpdatedUser",this.GetClientInfo(ClientInfoType.LoginUser); ucOrders.SetFieldValue("UpdatedDate",System.DateTime.Today); }
如何在UpdateComp的事件中去自行處理其他資料交易,而不必使用InfoTransaction元件? 在UpdateComp中的事件中,可以使用GetFieldCurrentValue()與GetFieldOldValue()來讀取Client所輸入的欄位新舊值,並透過ExecuteCommand()來自行下出SQL語法,為了讓此SQL命令能配合原來UpdateComp的Transaction須為同一個交易(同步Commit或RollBack),因此可以透過UpdateComp取得此Connection與Transaction,舉例如下: int QtyOld = UpdateComp1.GetFieldOldValue("Qty"); int QtyNew = UpdateComp1.GetFieldCurrentValue("Qty"); this.ExecuteCommand("update table2 set field = ....", UpdateComp1.conn, UpdateComp1.trans); 需要注意的地方,新增時只能用GetFieldCurrentValue,刪除的時候,只能用GetFieldOldValue。
在新增時,UpdateComp中使用GetFieldOldValue時,系統報錯。錯誤訊息:沒有可存取的 Original 資料.! ,這是為甚麼? 在UpdateComp的新增時,因為UpdateCom中並沒有各欄位的舊值內容,在新增的事件中,是不能使用GetFieldOldValue的方法。
UpdateComponent 中FieldAttrs屬性會應用在哪裡? FieldAttrs是為了給特殊功能使用的,並不是一定都須設定的,沒有設定也一樣可以正常insert或者update,一般的用法有: 1. 給某個欄位預設值,這個值不一定需要在Client端顯示,比如更改者,更改時間等等。 2. 是否需要回寫此欄位元,比如有些left join進來的欄位是不能回寫到資料庫的,可以在此設定不存檔,也有一些為了顯示用的計算欄位等等,都是同樣的用法。 3. 還可以定義是否需要checknull.不過,這個功能更多的是在Client端使用DefaultValidate或WebValidate來實現,畢竟到了後端確實時機晚了一些。
當該Table有設定後端資料庫的Trigger時,可能會出現多筆資料被異動錯誤,請問應該如何解決? 在UpdateComp在存檔的時候EEP會去判斷資料受到影響的筆數,也就是說只能有一筆資料影響才會是正確的交易,如果超過一筆或沒有資料被影響,這都是會被認為是錯誤的交易,所以才會出現上述問題。在EEP SP3之後的UpdateComp元件,增加了一個屬性RowAffectCheck,可以將其設為false,這樣系統就不會去檢查這個影響筆數。
在infocommand裡,當更新table裡面的值時,要如何同時更新另外一個table的資料? 方式一.在UpdateComponent的相關事件寫程式下insert or update的sql語句(為了包在同一個Transaction請在調用ExecuteSql或者ExecuteCommand方式時使用updateComp的conn和trans)。方式二.傳參數方式

Server偵錯

當前位置:首頁>常見問答>Server元件


開啟EEPNetServer,也將EEPNetServer設為起始專案,斷點也標示了,但偵錯程式都無法停在標示的斷點上? 這是因為Server端"熱插拔"的機制,會影響Debug的機制,可打開EEPNetServer的PackageManager,將上方的Load in Memory選項取消勾選,重啟Server後重試。
Server的偵錯方法? 首先我們關閉EEPNetServer,然後在Solution下將EEPNetServer設定為啟動項。接著點選工具列上的綠色 按鈕,此時EEPNetServer會自動啟動。 當Client為Win Form時,可以直接開啟EEPNetClient來進行Debug。若為WebForm時,請點開電腦的桌面的右下角的“ASP.Net開發伺服器”後,選擇根目錄URL的位址,並在開啟的頁面中選擇Login.aspx 在上面說的server和Client除錯,如果在除錯啟動後,我們發現紅色的實心圓 變成了空心圓 。在這種情況下,有兩種可能,第一是需要將除錯的Server端或者是Win Form的Client端重新建置;第二種則是除錯的啟動項設定錯誤,如希望除錯server程式,但啟動項設定為EEPNetClient。若您除錯的是Srvtools的情況下,出現這種問題,那麼請停止除錯,並重新建置Srvtools,然後執行InitEEP。

Server其他問題

當前位置:首頁>常見問答>Server元件


錯誤訊息:的KeyField[Srvtools.KeyItem]欄位不存在? 如果有Left join的欄位,請將Left Join的欄位放在sql語句的後半部分,比如: select Orders.*, CompanyName from Orders left join Customers on ...... 不要寫成:select CompanyName, Orders.* from Orders left join Customers on ......
使用InfoTransaction元件,希望符合條件再執行過帳 InfoTransaction元件有BeforeTrans事件,可以通過e.Cancel=true來取消。
InfoTransaction的BeforeTrans事件裡,該如何取得Client輸入的資料? 在BeforeTrans事件中可以通過UpdateComp.CurrentRow來讀到當前的Row, 如下: private void infoTransaction1_BeforeTrans(object sender, InfoTransactionBeforeTransEventArgs e) { int i = Convert.ToInt16(ucMaster.CurrentRow["Quantity"]); // 取得 ucMaster所對應的Quantity欄位值 …. }
server如何使用StoredProcedure? 只要使用InfoCommand元件即可呼叫StoredProcedure,將InfoCommand的CommandType設定為StoredProcedure,並以CommandText來設定StoredProcedure的名稱,然後利用InfoParameters建立StoredProcedure所要傳遞的參數即可,網站下載區中有專門的參考文件,如下: http://www.infolight.com.tw/download/file/InfoCommand%E4%BD%BF%E7%94%A8%E5%AD%98%E5%84%B2%E9%81%8E%E7%A8%8B.doc
如何在Server端使用StoredProcedure查詢?錯誤訊息:找不到預存程式 'SP_GET_USERSTOLIST? 在InfoCommand的CommandText只能填入你的預存程式名稱,而不是整個sql語句,如: CommandText=SP_GET_USERSTOLIST CommandType=StoredProcedure InfoParameters建立一InfoParameters,ParameterName=UserID ServiceManager要註冊一function專門呼叫此InfoCommand回傳object,就可以調用成功了 更多詳情,請參考 http://www.infolight.com.tw/download/file/InfoCommand%E4%BD%BF%E7%94%A8%E5%AD%98%E5%84%B2%E9%81%8E%E7%A8%8B.doc
如何在server上抓取當前login的User. 直接寫使用object[] user_id = this.GetClientInfo(ClientInfoType.LoginUser); This是指DataModule這個Clasee,在Server端都是以DataModule這個Class為範圍的。
寫了一個ServerMethod後始終在return傳回後,發生錯誤? 在Server Method Return值時,其陣列的第一個參數一定必須傳回0, (如 ret[0] 必須是0),這是EEP系統用的返回參數,0代表正常執行,1代表有錯誤發生,因此,如果你傳為不是0的值,系統都會認為發生了錯誤,但從第二個參數開始,你可以自由使用。
何時該使用 Server Method,使用 server method 有什麼好處? ServerMethod提供的是一種架構,非常自由,比如可以傳遞任意參數,可以返回任意結果,可以完成很多功能。因為在N-Tier架構中,不管是Windows Client還是IIS Server都不應該可以直接連線到Database Server才對(基於安全與流量管制理由),因此Client端要處理大量的資料或用程式自由存取資料庫,就必須藉由Server Method來處理,因此Server Method就好像Web Service一樣,提供所需的資料或商業邏輯的處理服務等等。至於什麼時候需使用Server Method,一般像大量資料的統計或者月結(年結)等都比較適合,這樣可以避免大量資料在server與client之間的傳輸。還有一些不需要client編輯操作的功能都可以放在server端用serverMethod來包裝處理。總之,Server Method用來處理與資料庫有關的商業邏輯,將U/I分離,因此Server Method也是一種SOA的架構之一。
Async call back後show另一form會當掉 源碼如下: public void p_rod052_back(object[] oret1) { string repn = "rod052"; cr070v.Form1 temp = new cr070v.Form1(); temp.repn = repn; temp.MdiParent = this.MdiParent; temp.WindowState = FormWindowState.Maximized; temp.Show(); } 異步呼叫與Form的show是有沖突. 以上述例子來看,解決方法: 1. 在public void p_rod052_back(object[] oret1)上面加一行程式: public delegate void ShowForm();//定義一個委託 2. 原public void p_rod052_back(object[] oret1)改為: { ShowForm call = delegate() { string repn = "rod052"; cr070v.Form1 temp = new cr070v.Form1(); temp.repn = repn; temp.MdiParent = this.MdiParent; temp.WindowState = FormWindowState.Maximized; temp.Show(); } this.Invoke(call); }
如何取得並顯示當前登入人數? 在Server上ServerConfig.UserLoginCount就是當前的登錄人數,可以通過ServerMethod來返回這個值.如: Client端 object[] ret = CliUtils.CallMethod("S001", "GetUserCount", null); Label1.Text = ret[1].ToString(); Server端 public object[] GetUserCount(object[] param) { return new object[]{0, ServerConfig.UserLoginCount}; }