2011年8月24日 星期三

[ASP.NET] Import Excel with linqtoexcel

上篇文章比較了以NPOI and EPPlus匯出Excel的效能,接著就是要介紹Import Excel了,雖然NPOI也可以Import Excel2003/2007,但我認識了linqtoexcel後,就毅然決然的選用LinqToExcel為我的Import利器了。
LinqToExcel為32位元的dll,所以如果在64位元遇到complier的問題時,請參閱轉載自網路的排除方法。 還有注意事項,轉載自官網:
Target x86 Platform Linq to Excel requires any projects referencing it to be built against the x86 platform target. See this link for detailed information on setting the platform target to x86. Note this only applies to compiling the project on x64 computers.
.Net 4 When using Linq to Excel in a .Net 4 app, make sure to change the target framework from the default client profile to the full .Net 4 framework. (Properties -> Application -> Target framework) The client profile cannot compile .Net 3.5 dlls.
檢而言之,只能跑在x64,跟.Net framework 3.5。 接著用官網的sample code介紹這好用的工具。
var excel = new ExcelQueryFactory("excelFileName");
var oldCompanies = from c in repo.Worksheet("US Companies") //worksheet name = 'US Companies'
                   where c.LaunchDate < new DateTime(1900, 0, 0)
                   select c;
首先讀取名字為"US Companies"的工作表,如果無法確定上傳的檔案的名稱,最好傳入index即可。
接著<Company>則是有一個名叫Company的Class與Excel 的欄位都一模一樣, 這樣檔案就會乖乖的資料吃到Company的集合物件, 並可以用linq的手法去做資料篩選,一整個就是美妙。

不過如果Excel欄位與Class無法設定成一樣的,那還是有法可解:
var excel = new ExcelQueryFactory("excelFileName");
excel.AddMapping(x => x.State, "Providence"); //maps the "State" property to the "Providence" column

var indianaCompanies = from c in excel.Worksheet()
                       where c.State == "IN" && c.Employees > 500
                       select c;
使用AddMapping去指定欄位間的關係,Excel欄位 "Providence"去指定對應到Company的State的欄位。

2011年7月26日 星期二

[ASP.NET] Export Excel with NPOI and EPPlus

NPOI:使用於(Excel2003及之前的版本),可寫出Excel2003(xls),可讀Excel2003 (xls)/ Excel2007(xlsx)

官網:
System Requirement:
  • VS2005 or VS2008 with .NET 2.0 Runtime (SP1)
  • vs2003 with .NET 1.1
  • medium trust environment in ASP.NET

EPPlus:EPPlus is a .net library that reads and writes Excel 2007/2010 files using the Open Office Xml format (xlsx).

官網:http://epplus.codeplex.com/
System Requirements:
  • .Net Framwork 3.5 or higher

    NPOI vs. EPPlus:比較匯出大量資料的時間

    2011年7月19日 星期二

    [ASP.NET] 解決Oracle IN clause 超過1000個參數

    不管在SQL Plus或其他Tool,甚至ASP.NET中,只要出現以下錯誤訊息:
    ORA-01795 maximum number of expressions in a list is 1000

    不用懷疑,就是你的SQL中,IN的參數超過1000個了。

    最快的解決方法有兩種:
    1. OR
    2. Union

    OR Sample如下:
    select * from TestTable where ID in (1,2,3,4,...,1000)
    union all
    select * from TestTable where ID in (1001,1002,...)
    

    Union Sample如下:
    select * from TestTable where ID in (1,2,3,4,...,1000) or ID in (1001,1002,...,2000)
    


    在ASP.NET中,Sample如下(使用OR):

    strSQL = "select * from TestTable where {0} ";
    int limitCount = 900;
                    double dLoopCycle = (IDs.Count / limitCount);
                    int loopCycle = Convert.ToInt32(Math.Ceiling(dLoopCycle));
                    loopCycle = loopCycle == 0 ? 1 : loopCycle;
    
                    string strIDs = string.Empty;
                    string strTempSQL = string.Empty;
                    //more than 1000 parameter would raise error
                    for (int i = 0; i < loopCycle; i++)
                    {
                        int rangeIndex = (i * limitCount);
                        List tempList = IDs.GetRange(rangeIndex, Math.Min(limitCount, IDs.Count - rangeIndex));
    
                        strIDs = string.Join(",", tempList.ToArray());
                        if (i == 0)
                            strTempSQL = string.Format("ID in ({0})", strIDs);
                        else
                            strTempSQL += string.Format("or ID in ({0}) ", strIDs);
                    }
    
    strSQL = string.Format(strSQL, strTempSQL);
    

    [ASP.NET] 解決Linq Contain 參數超過2100的錯誤

    在Linq使用Contain時,必須注意參數的個數,限制為2100為上限,錯誤訊息如下:
    The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Too many parameters were provided in this RPC request. The maximum is 2100.

    表示你踩到IN Parameter最多2100個的限制。

    以下為我的解決之道:

    double dLoopCycle = (containList.Count / 2000);
    int loopCycle = Convert.ToInt32(Math.Ceiling(dLoopCycle));
    loopCycle = loopCycle == 0 ? 1 : loopCycle;
    
    List result = new List();
    List tempResult = new List();
     //more than 2100 parameter would raise error
     for (int i = 0; i < loopCycle; i++)
     {
         int rangeIndex = (i * 2000);
         var tempList = containList.GetRange(rangeIndex, Math.Min(2000, containList.Count - rangeIndex));
    
         tempResult = (from r in DataContext.Test where tempList.Contain(r.ID) select r).ToList();
         result = result.Union(tempResult );
    }
    
    

    另外oracle的SQL也有IN Parameter不得超過1000個的限制,這個就會在後續的文章分享我的解決方式囉~~

    [ASP.NET] 解決Oracle IN clause 超過1000個參數

    2011年7月13日 星期三

    [ASP.NET] Nlog:記Log必備的好東西

    要瞭解Nlog初步認識一定必須先拜讀保哥的的大作,介紹好用函式庫:NLog - Advanced .NET Logging

    當然師傅引進門,詳細的設定就是要靠自己啦...
    就如保哥所說的,install之後就有完整的API文件跟範例,
    其實不外乎只要把 Nlog.config 設定好,就完成大半的工作了!!!

    我的設定主要:
    1.存成File的部分,七天回滾一次,自動刪除過期的Log,讓Disk不會被擠爆。
    2.寄出Mail的部分,集滿五個拉環才寄出,不會一個Message寄發信,讓我的信箱不被塞爆。

    首先附上我的Nlog.config