四虎精品视频-四虎精品成人免费网站-四虎黄色网-四虎国产视频-国产免费91-国产蜜臀97一区二区三区

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

系列文章導航:

Linq To Sql進階系列(一)從映射講起

Linq To Sql進階系列(二)M:M關系

Linq To Sql進階系列(三)CUD和Log

Linq To Sql進階系列(四)User Define Function篇

Linq To Sql進階系列(五)Store Procedure篇

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

Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別


動態的生成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

系列文章導航:

Linq To Sql進階系列(一)從映射講起

Linq To Sql進階系列(二)M:M關系

Linq To Sql進階系列(三)CUD和Log

Linq To Sql進階系列(四)User Define Function篇

Linq To Sql進階系列(五)Store Procedure篇

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

Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別


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;
        }

系列文章導航:

Linq To Sql進階系列(一)從映射講起

Linq To Sql進階系列(二)M:M關系

Linq To Sql進階系列(三)CUD和Log

Linq To Sql進階系列(四)User Define Function篇

Linq To Sql進階系列(五)Store Procedure篇

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

Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別


4,測試用例及反思
我們用下面的例子來測試下這個函數

            Customer c = new Customer();
            c.City 
= "London";
            c.Phone 
= "23236133";

            var q 
= db.Find<Customer>(c).ToList();

it知識庫Linq To Sql進階系列(六)用object的動態查詢與保存log篇,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 韩义生| 陈建斌电影| 爱奈| 暗黑破坏神2毁灭之王| 电视节目预告表| 摇曳庄的幽奈小姐| 曹查理新剧《三姐妹》| 少年的奇幻漂流记| 马德哈万| 我在江湖 电影| 麦当娜简历| 黄姓的研究报告| 飞头魔女电影完整版免费观看| 抖音登录网页版| 情动电影| 二胡独奏我的祖国| 徐有容| 《stag》电影在线观看| 姐妹们| 欧若拉歌词| 男同志gay免费视频| 爸爸的儿子| 张纪中个人简历| 间宫夕贵电影| 回收名表价格查询| 少年圆鱼洲 综艺| 那年秋天| 飞头魔女电影完整版免费观看| 电视剧《节妇》在线观看| 画魂缠身 电影| 国家励志奖学金个人主要事迹1500字| 电影频道直播| 艳妇乳肉豪妇荡乳ⅹxxooav| 反恐特战队2之猎影| 小小少年电影简介| 抖音安装| 男人不可以穷演员表| 爆操女人逼| 韩红个人资料| 变形金刚1免费完整版在线观看 | 三人行菲律宾|