天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Linq To Sql進(jìn)階系列(六)用object的動(dòng)態(tài)查詢(xún)與保存log篇

系列文章導(dǎo)航:

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

Linq To Sql進(jìn)階系列(二)M:M關(guān)系

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

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

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

Linq To Sql進(jìn)階系列(六)用object的動(dòng)態(tài)查詢(xún)與保存log篇

Linq To Sql進(jìn)階系列(七)動(dòng)態(tài)查詢(xún)續(xù)及CLR與SQL在某些細(xì)節(jié)上的差別


動(dòng)態(tài)的生成sql語(yǔ)句,根據(jù)不同的條件構(gòu)造不同的where字句,是拼接sql 字符串的好處。而Linq的推出,是為了彌補(bǔ)編程中的 Data != Object 的問(wèn)題。我們又該如何實(shí)現(xiàn)用object的動(dòng)態(tài)查詢(xún)呢?

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

根據(jù)這些基本的需求,我們來(lái)定義下面的函數(shù),為了實(shí)現(xiàn)這個(gè)函數(shù)對(duì)任何實(shí)體都是有用的,我們把它定義為generic的。為了不破壞Linq To Sql延遲加載的規(guī)矩,我們把它的返回類(lèi)型定義為IQueryable。如下:

public IQueryable<TEntity> Find<TEntity>(TEntity obj) where TEntity : class

系列文章導(dǎo)航:

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

Linq To Sql進(jìn)階系列(二)M:M關(guān)系

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

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

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

Linq To Sql進(jìn)階系列(六)用object的動(dòng)態(tài)查詢(xún)與保存log篇

Linq To Sql進(jìn)階系列(七)動(dòng)態(tài)查詢(xún)續(xù)及CLR與SQL在某些細(xì)節(jié)上的差別


2,原理
Linq To Sql支持用戶(hù)動(dòng)態(tài)生成lambda表達(dá)式。本文中所實(shí)現(xiàn)的方法,正是反射加lambda動(dòng)態(tài)表達(dá)式。我們先來(lái)看如何動(dòng)態(tài)生成lambda表達(dá)式。在Linq 中,lambda表達(dá)式會(huì)首先轉(zhuǎn)化為Expression Tree,本文并不詳解Expression Tree。Expression Tree是lambda表達(dá)式從code的形式轉(zhuǎn)化為data的結(jié)果,是一種更高效的在內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)。比如: 
Func<int,int> f = x => x + 1;                               // Code

Expression<Func<int,int>> e = x => x + 1;       // Data

第二個(gè),其實(shí)也就是第一個(gè)轉(zhuǎn)化后的形式。那好了,有了這個(gè)前提,我們就可以動(dòng)態(tài)構(gòu)造這個(gè)Expression Tree了。
// 先構(gòu)造了一個(gè)ParameterExpression對(duì)象,這里的c,就是Lambda表達(dá)中的參數(shù)。(c=>)                           
ParameterExpression param = Expression.Parameter(typeof(TEntity), "c"); 
//構(gòu)造表達(dá)式的右邊,值的一邊
Expression right = Expression.Constant(p.GetValue(obj, null));
//構(gòu)造表達(dá)式的左邊,property一端。
Expression left = Expression.Property(param, p.Name);
//生成篩選表達(dá)式。即c.CustomerID == "Tom"
Expression filter = Expression.Equal(left, right);
//生成完整的Lambda表達(dá)式。
Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(filter, param);
//在這里,我們使用的是and條件。
query = query.Where(pred);

3,反射在本方法中的作用
因?yàn)槲覀儾捎昧四0澹簿褪钦f(shuō),我們并不知道傳進(jìn)來(lái)的對(duì)象會(huì)有那些property,那反射在這里就提供一個(gè)很好的方法。我們可以通過(guò)反射去遍歷每一個(gè)property,只有判斷出該property的值不為null時(shí),才將其視為條件。該函數(shù)完整的代碼如下:

        public IQueryable<TEntity> Find<TEntity>(TEntity obj) where TEntity : class
        
{
            
//獲得所有property的信息
            PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public |
 BindingFlags.Instance);
            
//構(gòu)造初始的query
            IQueryable<TEntity> query = this.GetTable<TEntity>().AsQueryable<TEntity>();
            
//遍歷每個(gè)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;
        }

系列文章導(dǎo)航:

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

Linq To Sql進(jìn)階系列(二)M:M關(guān)系

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

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

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

Linq To Sql進(jìn)階系列(六)用object的動(dòng)態(tài)查詢(xún)與保存log篇

Linq To Sql進(jìn)階系列(七)動(dòng)態(tài)查詢(xún)續(xù)及CLR與SQL在某些細(xì)節(jié)上的差別


4,測(cè)試用例及反思
我們用下面的例子來(lái)測(cè)試下這個(gè)函數(shù)

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

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

it知識(shí)庫(kù)Linq To Sql進(jìn)階系列(六)用object的動(dòng)態(tài)查詢(xún)與保存log篇,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 青青草狠狠干 | 亚洲麻豆精品成人A在线观看 | 丝袜美腿美女被狂躁在线观看 | av在线不卡中文网 | 男人桶爽女人 | 纯肉合集(高H) | 美女教师朝桐光在线播放 | 伊人久久亚洲精品一区 | 美女图片131亚洲午夜 | 欧美人与善交大片 | 国产成人精品s8p视频 | 国精产品一区一区三区有限在线 | 麻豆XXXX乱女少妇精品 | 成人小视频在线观看 | 亚洲av欧美在我 | 媚药调教被撑到合不拢h | 中文字幕本庄优花喂奶 | 国产精品A久久777777 | 日本午夜精品一区二区三区电影 | 夜蒲团之5阳性之教 | 蜜桃日本MV免费观看 | 广东95后小情侣酒店自拍流出 | 国产亚洲精品品视频在线 | 巨大乳hdbbw 巨爆乳中文字幕爆乳区 | 暖暖 免费 高清 日本在线 | 十九岁韩国电影在线观看 | 阿力gv资源 | 99riav9 精品香蕉免费大视频 | 99精品国产电影 | CHINESE熟女老女人HD视频 | 日韩欧美国产免费看清风阁 | 色综合久久综合网观看 | 在线欧美免费人成视频 | 亚洲精品天堂无码中文字幕影院 | 芒果视频看片在线观看 | 亚洲 日韩 国产 中文视频 | 97在线国内自拍视频 | 久久精品综合电影 | 国产精品人妻无码久久久奥特曼 | 国产在线精品亚洲第一区 | 青草影院内射中出高潮-百度 |