2008年12月23日 星期二

Nullable data type conversion

今天寫了一個 function 來將 client post back 中 form 的資料寫回至物件中

不囉唆,直接看 code

        public static FormCollection FillTo(this FormCollection form, object target, Func<FormCollection, string, object> getValue)
        {
            Type targetType = target.GetType();
            foreach (var property in targetType.GetProperties())
            {
                //檢查 form 中有沒有值
                if (Array.IndexOf(form.AllKeys, property.Name) != -1)
                {
                    object value = getValue(form, property.Name);
 
                    if ((property.PropertyType == typeof(System.Guid)) || (property.PropertyType == typeof(System.Guid?)))
                        value = new Guid(value as string);
                    else if ((property.PropertyType == typeof(System.DateTime)) || (property.PropertyType == typeof(System.DateTime?)))
                        value = Convert.ToDateTime(value);
                    else if ((property.PropertyType == typeof(System.Int16)) || (property.PropertyType == typeof(System.Int16?)))
                        value = Convert.ToInt16(value);
                    else if ((property.PropertyType == typeof(System.Int32)) || (property.PropertyType == typeof(System.Int32?)))
                        value = Convert.ToInt32(value);
                    else if ((property.PropertyType == typeof(System.Int64)) || (property.PropertyType == typeof(System.Int64?)))
                        value = Convert.ToInt64(value);
                    else if ((property.PropertyType == typeof(System.Byte)) || (property.PropertyType == typeof(System.Byte?)))
                        value = Convert.ToByte(value);
                    else if ((property.PropertyType == typeof(System.Boolean)) || (property.PropertyType == typeof(System.Boolean?)))
                        value = BoolParseEX(value as string);
                    else if ((property.PropertyType == typeof(System.Char)) || (property.PropertyType == typeof(System.Char?)))
                        value = Convert.ToChar(value);
                    else if ((property.PropertyType == typeof(System.Decimal)) || (property.PropertyType == typeof(System.Decimal?)))
                        value = Convert.ToDecimal(value);
                    else if ((property.PropertyType == typeof(System.Double)) || (property.PropertyType == typeof(System.Double?)))
                        value = Convert.ToDouble(value);
                    else if ((property.PropertyType == typeof(string))) // || (property.PropertyType == typeof(string?)))
                        value = Convert.ToString(value);
                    else
                        throw new Exception(string.Format("value type not support!!   {0}", property.PropertyType.FullName));
 
                    try
                    {
                        property.SetValue(target, value, null);
                    }
                    catch
                    {
                        //ignore
                    }
                }
            }
            return form;
        }


因為 c# 2.0 加入了 Nullable 的原故,所以特別要做 Nullable 的判斷

2008年12月22日 星期一

Linq to Entity Problem


var query = DataEntities.CLD_CLASSDEF.Where(p => p.ID == new Guid(form["ID"])).FirstOrDefault();


會造成 Only parameterless constructors and initializers are supported in LINQ to Entities

解法為

var query = (from p in dataContext.CLD_CLASSDEF
where p.ID.CompareTo(cldDetailID) == 0
select p).FirstOrDefault();


原因 ??

我也不知道

下面這兩篇好像有討論到,有時間再看

http://mosesofegypt.net/post/2008/08/24/LINQ-to-Entities-what-is-not-supported.aspx
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/9dee0d13-490c-48aa-bad5-50768d3cedf1/

2008年12月12日 星期五

Generic Type Casting

class c1
{
public Department Department{get;set;}
}

class c2:c1
{
public new Department Department{get;set;}
}

class Department
{
}

class Department : Department
{
}


在這個狀況下 Department 該如何轉型呢??


public new Department Department
{
get
{
Object temp = base.Department;
return temp as Department;
}
set { }
}

2008年11月17日 星期一

GetChanges() Merge() DIY 版

發想:
由於之前是開發 Delphi 的程式。在 .net 2.0 中的 DataSet 我覺得就有 Delphi 的味道。所以就一直想找個在 Delphi 程式中的功能 DataSet.Delta。這個功能主要是要取出 DataSet 中改變的部份。以減少 size 方便上傳。
而在 .net 中對應的 Function 就是 GetChanges() 及 Merge() 這兩個 function
在實際使用後只想發出 亙亙亙 的聲音~
在目前開發的方式是採 MVC 的架構 Client 新增 Record只有一個Temp PK,需上傳至Server後才可以取得實際的 PK。但 GetChange() 及 Merge() 需要由 PK 才可以找出原先的 Record (為何不用 Record 的 RowCode 咧) 才 Merge 的起來。要不然就再多一筆資料給你看。要不然連 Modified 的 Row 也 Merge 不起來。 看來是 M$ 版本的功能太強大了,我實在不會用
試了老半天,決定開發 DIY 版的 Code。

需求:
ViewModel GetChanges() 回傳改變的 DataSet 集合
void Merge(ViewModel result) 將 result 中的資料寫回


用法:




TestVM actual= (TestVM)target.GetChanges();


//the new row
actual.TypedDataSet.DataTable3.Rows[0][2] = "newRow";
actual.TypedDataSet.DataTable3.Rows[0][1] = 8;
actual.TypedDataSet.DataTable3.Rows[0][0] = "i'm pk"; //this is PK

actual.TypedDataSet.DataTable2.Rows[0][2] = "dt2new";
actual.TypedDataSet.DataTable2.Rows[0][1] = 2;

actual.TypedDataSet.DataTable3.Rows[0][2] = "dt3new";
actual.TypedDataSet.DataTable3.Rows[0][1] = 3;

target.Merge(actual);

2008年11月14日 星期五

Create Instance By Type

本來以為這應該是 Reflection 裡的功能,沒想到找了半天找不到

原來兇手是 Activator 物件

System.Type type = this.GetType();
TSource vm = (TSource)System.Activator.CreateInstance(type, new object[] { this.UserID });
 
//TSource vm = new TSource(this.UserID);
 
foreach(DataTable dt in view.Tables)
{
    DataTable dtDest = vm.view.Tables[dt.TableName];
 
    foreach (DataRow dr in dt.Rows)
    {
        if (dr.RowState == DataRowState.Unchanged) continue;
        DataRow drDest = dtDest.NewRow();
        drDest.FillWith(dr);
        dtDest.Rows.Add(drDest);
    }
}
 
return vm;

上面的 Code 主要是要在 父類別中 Create 出子類別的 Instance

還是有更簡單的辦法呀??

2008年11月13日 星期四

ListView Insert 不能用 runat="server"

有沒有遇過神奇的事件??
最近遇到一個

就是 ListView 在 Insert Template 時會出現 神奇 Exception

ObjectDataSource“ObjectDataSource1”没有可以插入的值。请检查“values”字典是否包含值。

原始碼如下



<asp:ListView runat="server" ID="groupedList" DataSourceID="odbDetailCLD_SERIALDEF"
    EnableViewState="true" DataKeyNames="SERIALID" OnSelectedIndexChanging="groupedList_SelectedIndexChanging"
    InsertItemPosition="FirstItem" OnItemInserting="groupedList_ItemInserting">
    <LayoutTemplate>
        <table runat="server" id="table1">
            <tr runat="server" id="itemPlaceholder">
            </tr>
        </table>
    </LayoutTemplate>
    <ItemTemplate>
        <tr id="trItem" runat="server">
            <td>
                <%-- Data-bound content. --%>
                <asp:LinkButton ID="btnItemEdit" CommandName="Edit" runat="server">
                    <img id="imgItemEdit" runat="server" alt='<%#Eval("SerialName") %>' src='~/Image/edit.bmp' />
                </asp:LinkButton>
                <asp:LinkButton ID="NameLabel" runat="server" CommandName='Select' CommandArgument='<%#Eval("SerialID") %>'
                    Text='<%#Eval("SerialName") %>' />
            </td>
        </tr>
    </ItemTemplate>
    <EditItemTemplate>
        <tr id="tdEdit" runat="server">
            <td>
                <input id="Hidden1" type="hidden" runat="server" value='<%#Bind("SERIALID") %>' />
                <asp:LinkButton ID="LinkButton2" CommandName="Update" runat="server">
                    <img id="Img2" runat="server" alt='<%#Eval("SerialName") %>' src='~/Image/save.gif' />
                </asp:LinkButton>
                <asp:LinkButton ID="LinkButton1" CommandName="Cancel" runat="server">
                    <img id="imgEditEdit" runat="server" alt='<%#Eval("SerialName") %>' src='~/Image/cancel.gif' />
                </asp:LinkButton>
                系'a8t列'a6C課'bd?程'b5{名'a6W稱'ba?
                <asp:TextBox ID="txtEditSerialName" runat="server" Text='<%#Bind("SerialName") %>'></asp:TextBox>
            </td>
        </tr>
    </EditItemTemplate>
    <InsertItemTemplate>
        <tr id="tdInsert" runat="server">
            <td>
                <asp:LinkButton ID="btnSave" CommandName="Insert" runat="server">
                    <img id="imgInsertSave" runat="server" alt='<%#Eval("SerialName") %>' src='~/Image/save.gif' />
                </asp:LinkButton>
                <asp:LinkButton ID="btnCancel" CommandName="Cancel" runat="server">
                    <img id="imtInsertCancel" runat="server" alt='<%#Eval("SerialName") %>' src='~/Image/cancel.gif' />
                </asp:LinkButton>
                系'a8t列'a6C課'bd?程'b5{名'a6W稱'ba?
                <asp:TextBox ID="txtInsertSerialName" runat="server" Text='<%#Bind("SerialName") %>'></asp:TextBox>
            </td>
        </tr>
    </InsertItemTemplate>
</asp:ListView>




看出 Insert Template 那有問題了嗎??

對,我看了大約三個月吧,還是看不出來。
後來不死心將錯誤翻成英文,再請 google 大神幫忙找

"ObjectDataSource“ObjectDataSource1”没有可以插入的值。请检查“values”字典是否包含值。"
翻成
"asp.net listview there is no value to insert"

還真的給我找到了





I have found the problem.
The runat="server" on the InsertItemTemplate is causing the problem. Remove the runat="server" and
everything works fine.
Please shed some light on why this should cause a problem.
--
Philip





天殺的 runat="server"
為何 EditTemplate 可以
InsertTemplate 就不行呀~~

update 2008/11/17
神奇的事發生了。今天連 EditTemplate 也不行。
但 EditTemplate 中有兩個 Field
SerialID, SerialName
SerialID Bind 到一個 Hidden Field, SerialName Bind 到 TextBox。
為何 SerialName 就是給他變成 null >_<
把 的 runat="server" 拿掉後又好了 somebody tell me why ~~

2008年11月9日 星期日

為 VS2008 加入 Javascript 的 Intellisens

最近常在用 jQuery,但是 VS 的 Intellisens 都無法 Support
今天找到好方法

TIPS-為VS2008加入完整jQuery Intellisense

download 了 Hotfix(說明) 及 jQuery Document

將 jQuery.1.2.6.js 及 jQuery.1.2.6-vsdoc.js 放在同一個目錄就行了

使用時,只要引用了 jQuery.1.2.6.js

<script src="../NewFolder1/jquery.js" type="text/javascript"></script>


這個新的 Hotfix 會自動找到說明文件,並顯示出來。


2008年11月6日 星期四

設定 ASP.NET 的暫存目錄

因為裝了 Gavotte Ramdisk 目前有大約 800 M 的空間可以用
所以想把 ASP.NET 的暫存目錄改到 RAM DISK 中
看能不能加快 COMPILE 的速度

做法為有兩種

1. 修改 machine.config
machine.config 的位置在 C:\WINDOWS\Microsoft.NET\Framework\[Framework Version]\CONFIG
[Framework Version] 為你目前用的 framework 版本。不過因為 3.5 其實本體還是用 2.0 的所以3.0, 3.5 的版本還是得修改 v2.0 裡的 machine.config

2. 修改 web.config
這位置不用說了吧

加入

<system.web>

<compilation tempDirectory="[Template Folder]" debug="true"></compilation>

</system.web>





這樣子就行了

2008年10月6日 星期一

08/10/07 DB 重大更新

LTS_CLOSEREC --> 更改 PK 為 closeno

LTS_CLOSEROLLBACK

LTS_INTENTCOUSE -> PREID 新增感興趣的課程

2008年9月15日 星期一

VS.Net 2008 開 Web 專案會 Crash

http://www.intellij.net/forums/thread.jspa?threadID=273160&tstart=0

在開啟 Web 專案時會出錯
已經發生好久了。今天終於找出解決辦法,原來這是 vs.net 的 bug 呀

以下為解決方法

The workaround is to modify web.config:
1) add reference to System.Core before all other assembly references
2) move configSections element to the end of the web.config file

照上面做就行了

2008年8月10日 星期日

How to find the max row per group in SQL without subqueries

查詢 最大值的 row

http://www.xaprb.com/blog/2007/03/14/how-to-find-the-max-row-per-group-in-sql-without-subqueries/

2008年7月22日 星期二

ASP.NET Connection 管理

理論上,在一次的 page request / webservice request 時應該都只產生一次的 db connection
之前的寫法 connection 會 open close 好幾次

目前改寫為 ConnectionFactory.Instance.GetConnection();
GetConnection 時會連線到 DB,保證在同一個 instance 時只會有一個 Connection

那在何時才將 Connection Close 呢??
目前是寫在 Global.asax Event

void Application_PostRequestHandlerExecute(object sender, EventArgs e)
{
ConnectionFactory.DisposeInstance();
}

但 ConnectionFactory.Instance 是在 Application 階層。
在同一個 Application 的期間只有一個 instance 存在。所以在多人使用時會有問題
所以 singleton 在 asp.net 使用時要注意呀

2008年7月16日 星期三

VM Ware Upgrad problem

VMWare Server upgrade 至 2.00 build 101586 時 在安裝了新的 vm tools後

之前執行好好的 AD 出現了問題

1. 網卡只剩下 10M 的速度,不再是 1g
2. 原有的 .1 的位址無法設定

解法
1. Upgrade 後網卡變成 AMD PCNet Adapter #2, 將 Driver 改為 VMware Accelerate AMD PCNet Adapter 速度就會提昇為 1G。
2. 在設定手動位址時,會有訊息。大致是說原有 .1 的位址被舊網卡給佔住了,同時運行時會有問題。 會問說是否要設定新的位址。 選擇 "否" 。 如此就可以運行了

2008年6月12日 星期四

Visual C# 3.0 新語法筆記




Visual C# 3.0 新語法筆記


摘錄如下
  • 隱含型別宣告 (Local Variable Type Inference)
  • 自動執行屬性 (Auto-Implemented Properties)
  • 匿名型態 (Anonymous Types)
  • 物件初始化 (Object Initializers)
  • 集合初始化 (Collection Initializers)
  • 擴展方法 (Extension Methods)
  • Lambda 表達式 (Lambda Expression)
  • Lambda 表達式樹 (Lambda Expression Trees)

Lambda小心得

C# 3.0 裡頭有有一個新功能叫 Lambda
突然覺得,有很 Strategy Pattern 的感覺
可以即時的抽換演算法

但是看網路上的範例已經捉不到頭緒
使用時機為何?? 還要再想想才知。

這有一篇文章寫的還滿清楚的
C# 3.0 - Lambda Expressions

2008年6月10日 星期二

ORM Survey

這兩天在 Survey OR Mapping 的方式
有找到幾個 solution

1. MyGeneration
這是一個 Open Source 的 Code Generator
可以依DB Schema 產生出 Entity 完全以物件的方式來做查詢的工作
看來還滿好用的

public void JoinWithArithmeticExpressionOrderByCalulatedColumn()
{
// Notice we create a calulated column based on the TotalSales, then Order by it descending
CustomerQuery cust = new CustomerQuery();
OrderQuery order = new OrderQuery();
OrderItemQuery item = new OrderItemQuery();

cust.Select(cust.CustomerName, (item.Quantity * item.UnitPrice).Sum().As("TotalSales"));
cust.InnerJoin(order).On(order.CustID == cust.CustomerID);
cust.InnerJoin(item).On(item.OrderID == order.OrderID);
cust.GroupBy(cust.CustomerName);
cust.OrderBy("TotalSales", esOrderByDirection.Descending);

CustomerCollection coll = new CustomerCollection();
coll.Load(cust);
}

2008/06/12 補充
其實上面說的有點錯誤
MyGenerator 只是一個 Code Generator, 要產生如上面一樣的 Code 必需要有 Template 的搭配。
上面的 Code 是由一家名為 Entity Space的公司所提供,所以是要錢的~

如果不想要花錢,MyGenerator 網站上還有提供一套 dOOdads 這就很類似以前所用的 DAO的架構了。

所以還是來學一下 NHibernate 比較實在。



2. NHibernate
就是 Hibernate for .Net 啦~
是由 Java 開始發展到 .Net 來的。這是一個有很多大型專案測試過的。穩定性十足

3. CSLA
這並不是 ORMapping 的 solution。他比較像是 Entity Framework
阿源哥哥的軟體組裝工廠裡有一些簡單的介紹

4. Linq to Sql
這是 .Net Framwork 3.5 裡頭新的功能,還在研究當中