2009年3月31日 星期二

Sql Server Trigger: 當只有某幾欄被更新時

寫了一個 after trigger,如下

create trigger [dbo].[tr_afterUpdateTable] on [dbo].[MyTable]
after update
as
begin
	set nocount on
	//… my work
end

但是,當任何MyTable欄位的資料被更新時,這個 trigger 就會被觸發,就會跑很久。

不太妙。找到了 http://msdn.microsoft.com/zh-tw/library/ms186329.aspx ,但範例似乎不太對,因此修改了一下。如下,才能跑。

create trigger [dbo].[tr_afterUpdateTable] on [dbo].[MyTable]
create trigger [dbo].[tr_afterUpdateTable] on [dbo].[MyTable]
after update
as
begin
	set nocount on
	IF (SUBSTRING(COLUMNS_UPDATED(),1,1) & 6) > 0
	begin
		//當第2欄或第3欄被更新時
		// power(2, 2-1) + power(2, 3-1) = 6
		//… my work
	end
end

MSDN 的範例還是會有錯誤的時候哦!

不建議在 asp.net 上使用 office Interop 的原因

在Web solution 上,客戶常有一個需求。以 Excel 檔匯入資料,或匯出資料成Excel檔案。

匯出成 Excel 的方法,之前已有討論過了, 但不少的同事還是喜歡用 Interop 的方式。。

不建議。因為我之前也用過,下場蠻慘的。

http://support.microsoft.com/kb/257757

此篇介紹微軟非常不建議直接在伺服器上安裝Microsoft Office 作為solution 的原因及建議。

Entity Framework: Database table 必須有 primary key

今天又想使用 entity framework 來計算 project server 2003 中,某一專案被專案經理審核接受的總工時。
找了一下,似乎 dbo.MSP_CUBE_ASSN_FACT 裡的資料可以使用,雖然必須 build cube 後才能讀到最新的值。

問題是,當我在 Visual Studio 2008 Entity designer ,使用 “update mode from database”,新增這個 table 時,一點作用也沒有,entity desinger 也沒有出現任何訊息。

原因呢?出在dbo.MSP_CUBE_ASSN_FACT 並沒有 primary key.

該 table 為了匯入時的效能,並沒有任何的 constraint,包括了 primary key。
但 entity desinger 也該出現一點訊息吧!

另外,這也大概是 Entity Framework 的一個缺點呢。雖然這是 by design 的。

2009年3月27日 星期五

Web Performance Turning 教學

今日無意間看到的中文 msdn 教學。

詳盡實用。開發 asp.net 的朋友們不得不看哦!

Web Performance Turning

http://msdn.microsoft.com/zh-tw/dd547432.aspx

2009年3月23日 星期一

2009年3月20日 星期五

IE 8 正式版出來了

IE 8 正式版出來了。

http://www.microsoft.com/windows/internet-explorer/worldwide-sites.aspx

自己挑一個語言吧。

2009年3月17日 星期二

Project 讀取大綱

最近又重操舊業了。又是 Project Server 2003.

原本的目的,是要讀取 Project Server 上某一專案的實際完成百分比。

下面的方法,原意是使用 Office DOM 來取得專案資訊。
這樣的方法,可以找到許多資料,但怎麼找也找不到實際完成百分比。

static void Main(string[] args)
    {
      ApplicationClass application = new ApplicationClass();
      application.Visible = true;
      bool opened = application.FileOpen(@"<>\伺服器上的專案.已發佈", 
        true, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
PjPoolOpen.pjPoolReadOnly, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

      Project p = application.ActiveProject;
      short i = (short) p.PercentComplete; //完成百分比
      short i2 = (short)p.PercentWorkComplete; //工時完成百分比

      foreach (OutlineCode item in p.OutlineCodes)
        Console.WriteLine(item.Name + item.FieldID.ToString()); //大綱
    }

注意到上面這一段程式,必須先執行 Project 2003 上連線到 Project Server 後再執行該程式。否則會有錯誤發生。

另外,Project Server 上的專案,必須以 <>\ 開頭來載入,這是比較奇怪的地方

更新!
可以讀取實際完成百分比了。而且也可以指定 status date 哦!程式片斷如下

private static short GetPhysicalPercentComplete(ApplicationClass application, string webProjName,
      DateTime statusDate)
    {
      bool opened = application.FileOpen(webProjName,
        true, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
PjPoolOpen.pjPoolReadOnly, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

      Project p = application.ActiveProject;
      p.StatusDate = statusDate;
      application.CalculateProject();
      Thread.Sleep(500);
      short physicalPercentComplete = (short)p.Tasks.get_UniqueID(0).PhysicalPercentComplete;
      application.FileClose(PjSaveType.pjDoNotSave, true);

      return physicalPercentComplete;
    }

2009年3月4日 星期三

Entity Framework: Update Model from database

LINQ to SQL 好雖好用,但有一點卻是大扣分。
當一個 table 已經製作好 dbml 之後,又修改了 table schema時,就必須重拉一次 dbml 了。

雖然不是很麻煩,但總是一件必須擔心忘了作的事。

Entity Framework 也有相同的需求,但作的比 LINQ to SQL 好得多了。
它只需要「更新」一下即可。

假設之前已經作好了 Table_1 後,原來 MyName 的型別為 char(10),需要改變為 nchar(10)。
此時需要的步驟如下:

  1. 在 entity designer 上按右鍵,點擊「Update Model from Database」

image

   2.   選「Refresh」頁後,展開「Tables」,選擇要更新 schema 的 Table_1,再按「Finish」即可。

image

這樣的步驟的確比 LINQ to SQL 好上一些,只差沒有自動偵測是否schema是否有新版了。

2009年3月3日 星期二

ASP.NET: 長時間的工作,取得目前進度到第n筆

在 asp.net 的應用程式中,最怕的一種需求,莫過於大量資料匯入,客戶又要求以 Web form 來呈現,並要求匯入的進度。

也就是說,畫面需要呈現目前進行到第幾筆,總共幾筆。

以下是我的實作。 實作分成兩部份,一個是伺服器端的同步,也就是一般的寫法。另一個則是伺服器端的非同步。

在 asp.net 的應用程式中,最怕的一種需求,莫過於大量資料匯入,客戶又要求以 Web form 來呈現,並要求匯入的進度。

也就是說,畫面需要呈現目前進行到第幾筆,總共幾筆。

以下是我的實作。 實作分成兩部份,一個是伺服器端的同步,也就是一般的寫法。另一個則是伺服器端的非同步。

aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default"
  Async="true" AsyncTimeout="1" %>




  

  



  

Code Behind

using System;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;

namespace WebApplication1
{
  public partial class _Default : System.Web.UI.Page
  {
    private static SlowTask slowTask = null;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    [ScriptMethod]
    [WebMethod]
    public static string GetTaskCurrentProgress()
    {
      return string.Format("{0}/{1} : {2}", slowTask.CurrentCount, slowTask.TotalCount, 
        slowTask.GetAsyncTaskProgress());
    }

    public void RunItAsync()
    {
      slowTask = new SlowTask(1000);
      PageAsyncTask asyncTask1 = new PageAsyncTask(slowTask.OnBegin, slowTask.OnEnd, null, "Async", true);
      RegisterAsyncTask(asyncTask1);
    }

    [ScriptMethod]
    [WebMethod]
    public static void RunItSync()
    {
      slowTask = new SlowTask(1000);
      slowTask.ExecuteAsyncTask();
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
      RunItAsync();
      Page.ClientScript.RegisterStartupScript(typeof(string), "ok", "");
    }
  }
}

關於 SlowTask 的程式如下,主要是封裝長時間工作的內容

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;

namespace WebApplication1
{
  public class SlowTask
  {
    private readonly int totalCount;
    public int TotalCount
    {
      get
      {
        return totalCount;
      }
    }

    public SlowTask(int count)
    {
      totalCount = count;
    }
    private String taskGrogress;
    private AsyncTaskDelegate dlgt;

    protected delegate void AsyncTaskDelegate();

    public String GetAsyncTaskProgress()
    {
      return taskGrogress;
    }

    public void ExecuteAsyncTask()
    {
      Random r = new Random(5);
      for (int i = 0; i < totalCount; i++)
      {
        Thread.Sleep(10 * r.Next(5));
        CurrentCount++;
      }
    }

    public int CurrentCount { get; set; }

    public IAsyncResult OnBegin(object sender, EventArgs e,
        AsyncCallback cb, object extraData)
    {
      taskGrogress = "AsyncTask started at: " + DateTime.Now + ". ";

      dlgt = new AsyncTaskDelegate(ExecuteAsyncTask);
      IAsyncResult result = dlgt.BeginInvoke(cb, extraData);

      return result;
    }

    public void OnEnd(IAsyncResult ar)
    {
      taskGrogress += "AsyncTask completed at: " + DateTime.Now;
      dlgt.EndInvoke(ar);
    }

    public void OnTimeout(IAsyncResult ar)
    {
      taskGrogress += "AsyncTask failed to complete because it exceeded the AsyncTimeout parameter.";
    }
  }
}

畫面如下

image

 

AJAX 的部份,可參考 AJAX 之 PageMethod
由實驗得知,兩種實作起來,伺服器端同步的AJAX效果比較好,但伺服器端非同步的伺服器資源使用率會較高。

程式碼可由這裡下載

Share with Facebook