一步一步學Linq to sql(一):預備知識


什么是Linq to sql

  Linq to sql(或者叫DLINQ)是LINQ.NET語言集成查詢)的一部分,全稱基於關系數據的 .NET 語言集成查詢,用於以對象形式管理關系數據,並提供了豐富的查詢功能,它和Linq to xmlLinq to objectsLinq to datasetLinq to entities等組成了強大的LINQ

  要學好LINQ查詢語法,就不得不先理解C# 3.0的一些新特性,下面一一簡單介紹。

 

隱含類型局部變量

            ///隱含類型局部變量
            var age = 26;
            var username = "aehyok";
            var userlist = new[] { "a", "b", "c" };
            Console.WriteLine(string.Format("姓名為{0}年齡為{1}",username,age));
            foreach (var user in userlist)
            {
                Console.WriteLine(user);
            }

  純粹給懶人用的var關鍵字,告訴編譯器(對於CLR來說,它是不會知道你是否使用了var,苦力是編譯器出的),你自己推斷它的類型吧,我不管了。但是既然讓編譯器推斷類型就必須聲明的時候賦值,而且不能是null值。注意,這只能用於局部變量,用於字段是不可以的。

匿名類型

            ///匿名類型
            var data = new {username = "aehyok",age = 26};
            Console.WriteLine("username:{0} age:{1}", data.username, data.age);

  匿名類型允許開發人員定義行內類型,無須顯式定義類型。常和var配合使用,var用於聲明匿名類型。定義一個臨時的匿名類型在LINQ查詢句法中非常常見,我們可以很方便的實現對象的轉換和投影。

擴展方法

 

   public static class helper
    {
        public static bool IsNullOrEmpty(this string s)
        {
            return string.IsNullOrEmpty(s);
        }

        public static bool In(this object o, IEnumerable b)
        {
            foreach (object obj in b)
            {
                if (obj == o)
                    return true;
            }
            return false;
        }
    }

            ///擴展方法
            Console.WriteLine(string.Format("字符串aaa{0}空的", "aaa".IsNullOrEmpty() ? "是" : "不是"));
            Console.WriteLine("1".In(new[] { "1", "2", "3" }));

  很多時候我們需要對CLR類型進行一些操作,苦於無法擴展CLR類型的方法,只能創建一些helper方法,或者生成子類。擴展方法使得這些需求得意實現,同時也是實現LINQ的基礎。定義擴展方法需要注意,只能在靜態類中定義並且是靜態方法,如果擴展方法名和原有方法名發生沖突,那么擴展方法將失效。

自動屬性

    public class Person
    {
        public string username { get; protected set; }

        public int age { get; set; }
        public Person()
        {
            this.username = "aehyok";
        }
    }

            ///自動屬性
            Person p = new Person();
            Console.WriteLine(p.username);

        意義不是很大,純粹解決機械勞動。編譯器自動為你生成get、set操作以及字段,並且你不能使用字段也不能自定義get、set操作,不過你可以分別定義get和set的訪問級別。

對象初始化器

 

    public class PersonTest
    {
        public string username { get; set; }
        public int age { get; set; }
        public override string ToString()
        {
            return string.Format("username:{0} age:{1}", this.username, this.age);
        }
    } 

            ///對象初始化器
            PersonTest pp = new PersonTest {  username="aehyok",age=26};
            Console.WriteLine(pp.ToString());
            Console.ReadLine();

       編譯器會自動為你做setter操作,使得原本幾行的屬性賦值操作能在一行中完成。這里需要注意:

       允許只給一部分屬性賦值,包括internal訪問級別

         可以結合構造函數一起使用,並且構造函數初始化先於對象初始化器執行

集合初始化器

繼續使用對象初始化的對象PersonTest

            var persons = new List<PersonTest> {
            new PersonTest {username = "a", age=1}, 

            new PersonTest {username = "b", age=2}};

            foreach (var ps in persons)

                Console.WriteLine(ps.ToString());

  編譯器會自動為你做集合插入操作。如果你為Hashtable初始化的話就相當於使用了兩個對象初始化器。

Lambda表達式

 

            ///Lambda表達式
             var list = new [] { "aa", "bb", "ac" };
            var result = Array.FindAll(list, s => (s.IndexOf("a") > -1));
            foreach (var v in result)

其實和2.0中的匿名方法差不多,都是用於產生內聯方法,只不過Lambda表達式的語法更為簡潔。語法如下:

       (參數列表) => 表達式或者語句塊

其中:

參數個數:可以有多個參數,一個參數,或者無參數。

表達式或者語句塊:這部分就是我們平常寫函數的實現部分(函數體)。

前面的示例分別是1個參數的例子,下面結合擴展方法來一個復雜的例子:

 

    public static class LambdaTest
    {
        public static int oper(this int a, int b, mydg dg)
        {
            return dg(a, b);
        }
    }

public delegate int mydg(int a, int b);

            ///Lambda表達式 擴展方法  委托
            Console.WriteLine(1.oper(2, (a, b) => a + b));
            Console.WriteLine(2.oper(1, (a, b) => a - b));

 

查詢句法

 

            ///查詢句法
            var personss = new List<PersonTest> {
 
                new PersonTest {username = "a", age=19}, 

                new PersonTest {username = "b", age=20},
 
                new PersonTest {username = "a", age=21}, 

            };
            var selectperson = from pss in personss 
                               where pss.age >= 20 
                               select pss.username.ToUpper();

            foreach (var psss in selectperson)
            {
                Console.WriteLine(psss);
            }

  查詢句法是使用標准的LINQ查詢運算符來表達查詢時一個方便的聲明式簡化寫法。該句法能在代碼里表達查詢時增進可讀性和簡潔性,讀起來容易,也容易讓人寫對。Visual Studio 對查詢句法提供了完整的智能感應和編譯時檢查支持。編譯器在底層把查詢句法的表達式翻譯成明確的方法調用代碼,代碼通過新的擴展方法和Lambda表達式語言特性來實現。上面的查詢句法等價於下面的代碼:

var selectperson = personss.Where(p=>p.age>=20).Select(p=>p.username.ToUpper());

 

總結

  LINQ查詢句法可以實現90%以上T-SQL的功能(由於T-SQL是基於二維表的,所以LINQ的查詢語法會比T-SQL更簡單和靈活),但是由於智能感應的原因,select不能放在一開始就輸入。

  示例代碼下載地址http://files.cnblogs.com/aehyok/Linq%E9%A2%84%E5%A4%87%E7%9F%A5%E8%AF%86.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM