• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    Linq To Sql進階系列(六)用object的動態查詢與保存log篇

    發布: 2008-5-07 13:47 | 作者: 網絡轉載 | 來源: 本站原創 | 查看: 313次 | 進入軟件測試論壇討論

    領測軟件測試網 動態的生成sql語句,根據不同的條件構造不同的where字句,是拼接sql 字符串的好處。而Linq的推出,是為了彌補編程中的 Data != Object 的問題。我們又該如何實現用object的動態查詢呢?

      1,用object的查詢是什么?
      我們可以簡單的舉這么一個例子。我們到公安局查找一個人。首先,我們會給出他的一些特征,比如,身高多少,年齡多少,性別,民族等。那么,我們把這個人的一些特征輸入電腦。我們希望,電腦能給我們返回這個人的信息。而實際上,有相同特征的人太多了,常常返回一個集合。那讓我們把這個過程抽象到程式里。我們需要new出來一個對象。這個對象包含了我們能知道的基本信息。而后,把這個對象傳給Linq To Sql,等待返回結果。

      根據這些基本的需求,我們來定義下面的函數,為了實現這個函數對任何實體都是有用的,我們把它定義為generic的。為了不破壞Linq To Sql延遲加載的規矩,我們把它的返回類型定義為IQueryable。如下:
    public IQueryable<TEntity> Find<TEntity>(TEntity obj) where TEntity : class
      思路出來了,先new出來一個對象,然后把對象傳給這個函數,我們渴望它能返回與這個對象匹配的結果集。為了讓它和DataContext有關系,我們把這個函數放到DataContext的partial類里。鼠標右擊Linq To Sql文件,選擇view code,這個時候,vs會為你創造一個DataContext的partial類,其擴展名比影射文件少了中間的desiger。大家要注意,你如果想自己修改影射文件,請放到這個文件里。這樣當影射code被刷新時,才不會沖掉你自己的修改。先大體描述下我們的思路。
    NorthwindDataContext db = new NorthwindDataContext(); //先new出一個對象 Customer c = new Customer(); //添入我們知道的最基本的信息,可以從ui獲得 c.City = "London"; c.Phone = "23236133"; //call函數find返回結果 var q = db.Find<Customer>(c);
      2,原理
      Linq To Sql支持用戶動態生成lambda表達式。本文中所實現的方法,正是反射加lambda動態表達式。我們先來看如何動態生成lambda表達式。在 Linq 中,lambda表達式會首先轉化為Expression Tree,本文并不詳解Expression Tree。Expression Tree是lambda表達式從code的形式轉化為data的結果,是一種更高效的在內存中的數據結構。比如:
    Func<int,int> f = x => x + 1; // Code Expression<Func<int,int>> e = x => x + 1; // Data
      第二個,其實也就是第一個轉化后的形式。那好了,有了這個前提,我們就可以動態構造這個Expression Tree了。
    // 先構造了一個ParameterExpression對象,這里的c,就是Lambda表達中的參數。(c=>) ParameterExpression param = Expression.Parameter(typeof(TEntity), "c"); //構造表達式的右邊,值的一邊 Expression right = Expression.Constant(p.GetValue(obj, null)); //構造表達式的左邊,property一端。 Expression left = Expression.Property(param, p.Name); //生成篩選表達式。即c.CustomerID == "Tom" Expression filter = Expression.Equal(left, right); //生成完整的Lambda表達式。 Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(filter, param); //在這里,我們使用的是and條件。 query = query.Where(pred);
      3,反射在本方法中的作用
      因為我們采用了模板,也就是說,我們并不知道傳進來的對象會有那些property,那反射在這里就提供一個很好的方法。我們可以通過反射去遍歷每一個property,只有判斷出該property的值不為null時,才將其視為條件。該函數完整的代碼如下:
    public IQueryable<TEntity> Find<TEntity>(TEntity obj) where TEntity : class { //獲得所有property的信息 PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); //構造初始的query IQueryable<TEntity> query = this.GetTable<TEntity>().AsQueryable<TEntity>(); //遍歷每個property foreach (PropertyInfo p in properties) { if (p != null) { Type t = p.PropertyType; //加入object,Binary,和XDocument, 支持sql_variant,imager 和xml等的影射。 if (t.IsValueType || t == typeof(string) || t == typeof(System.Byte[]) || t == typeof(object) || t == typeof(System.Xml.Linq.XDocument) || t == typeof(System.Data.Linq.Binary)) { //如果不為null才算做條件 if ( p.GetValue(obj, null) != null) { ParameterExpression param = Expression.Parameter(typeof(TEntity), "c"); Expression right = Expression.Constant(p.GetValue(obj, null)); Expression left = Expression.Property(param, p.Name); Expression filter = Expression.Equal(left,right); Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(filter, param); query = query.Where(pred); } } } } return query; }

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: LINQ Linq sql SQL Sql 進階 object log

    21/212>

    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>