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 會自動找到說明文件,並顯示出來。