黃忠成

風雪之閣- i live,so i writing
文章數 - 96, 回應數 - 29, 引用數 - 0


關於我:



黃忠成

  • 資深.NET 技術顧問
  • Run! PC 雜誌專欄作者
  • 程序員雜誌文章作者
  • PC Magazine 雜誌專欄作者
  • MSDN 專欄作者
  • MSDN 特約專屬講師
  • Microsoft .NET專屬講師
  • 台灣微軟特約技術顧問
  • 台灣微軟最有價值專家


  • 批評,指教,鼓勵, 請 寫信給我
    轉載文章請使用連結模式,
    請勿整篇Copy! 謝謝!


    我所提供的教育訓練:

    Windows Forms
    ASP.NET 2.0
    如有課程需要,請與我聯絡!

  • 我的著作:

  • 文章標籤

    全部標籤

    每月文章

    文章分類

    Cast的妙用:泛用LINQ 語句

     

    Cast的妙用:泛用LINQ 語句
     
    /黃忠成
     
    什麼是泛用LINQ 語句
     
       泛用LINQ語句的概念很簡單,在一些情況下,我們會有需求使用同一段程式碼來對不同資料表做查詢,這在ADO.NET中很容易達到,見下例:

    static void PrintCustomerID(SqlDataReader reader)
    {
        Console.WriteLine(reader.GetString(reader.GetOrdinal("CustomerID")));
    }
    此函式接受一個Reader物件,然後頃印CustomerID欄位值,這不受限於SqlDataReader所選取的Schema或是資料表,只要Schema中有CustomerID欄位即可。
    不過,這樣的手法在LINQ這種Typed-Query(具型別查詢語句)模式下,並沒有很直覺的寫法,因為你不能寫下下面的句子。

    static void Test2(int index)
    {
          var query;
          DataClasses1DataContext context = new DataClasses1DataContext();
          context.Log = Console.Out; //for log only,you can remove it.
          if (index == 1)
              query = context.Customers;
          else
              query = context.Orders;
     
          var result = from s1 in query where s1.CustomerID.Contains("V")
                       select s1;
          foreach (var item in result)
          {
             Console.WriteLine(item.CustomerID);
          }
    }
    編譯器會抱怨,var的變數必須在宣告時指定。
    那要如何在LINQ To SQL或是LINQ To Entites達到同樣的效果呢?這有幾個方法可以做到。

    1、使用ExecuteQuery,並使用另一個Typed物件來接收回傳集。
    2、使用實體類別(Entity Class)繼承。
    3、使用Castpartial class
    12對熟悉LINQ To SQL的讀者應該不難,所以我就不再贅述了,第三個手法是較少見的,我們可以運用partial class機制,讓Entity Classes實作特定介面,然後以Cast函式來達到目的。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Linq;
    using System.Data.SqlClient;
     
    namespace ConsoleApplication39
    {
        class Program
        {
            static void Main(string[] args)
            {
                Test(1);
                Console.WriteLine("------");
                Test(0);
                Console.ReadLine();
            }
     
            static void Test(int index)
            {
                IQueryable<IGenericBaseClass> query = null;
                DataClasses1DataContext context = new DataClasses1DataContext();
                context.Log = Console.Out; //for log only,you can remove it.
                if(index == 1)
                    query = context.Customers.Cast<IGenericBaseClass>();
                else
                    query = context.Orders.Cast<IGenericBaseClass>();
     
                var result = from s1 in query where s1.CustomerID.Contains("V") select s1;
                foreach (var item in result)
                {
                    Console.WriteLine(item.CustomerID);
                }
            }
        }
     
        public interface IGenericBaseClass
        {
            string CustomerID { get; set; }
        }
     
        partial class Customers : IGenericBaseClass
        {
        }
     
        partial class Orders : IGenericBaseClass
        {
        }
    }
    仔細揣摩上面的程式碼,我相信你會找到一個不一樣的LINQ應用手法。

    posted on 2008/7/8 16:09 | 我要推薦 | 閱讀數 : 275 | 文章分類 [ LINQ ] 訂閱

    Feedback

    目前沒有回應.

    回應

    標題
    姓名
    電子郵件
    個人網頁
    內容 
      登入後使用進階評論  
    Please add 8 and 8 and type the answer here:

    Powered by: