一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

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

系列文章導(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)查詢與保存log篇

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


在上面一篇文章Linq To Sql進(jìn)階系列(六)中,我們提到了使用object的動(dòng)態(tài)查詢。本文在上文的基礎(chǔ)上,再做更加深入的引申。同時(shí)修正上文中一些不妥的地方。

1, object的動(dòng)態(tài)查詢續(xù)
首先要做的事情,就是將Find的函數(shù)改成擴(kuò)展方法。擴(kuò)展方法只能放在靜態(tài)類里,而且它的第一個(gè)參數(shù)必須帶this關(guān)鍵字。在上文中,作者留下了一個(gè)迷題。當(dāng)需要or條件時(shí),又該如何做呢?本文也將這個(gè)問(wèn)題給出回答。但是對(duì)于動(dòng)態(tài)Like的條件,筆者依然還沒(méi)有找到一個(gè)較好的方法。為了增加or條件,函數(shù)的聲明也再一次被改動(dòng)。如下:
    public static IQueryable<TEntity> Find<TEntity>(this IQueryable<TEntity> source, TEntity obj, bool isAnd) where TEntity : class
在上文中,我們還碰到了System.Nullable<int>此類類型不支持的問(wèn)題。其實(shí)這個(gè)地方主要原因在于我們構(gòu)造right端的Expression Tree時(shí),沒(méi)有給它參數(shù)。那么這個(gè)問(wèn)題通過(guò)Expression right = Expression.Constant(p.GetValue(obj, null), p.PropertyType); 可以得到修復(fù)。那整個(gè)函數(shù)修改后,如下:

    public static IQueryable<TEntity> Find<TEntity>(this IQueryable<TEntity> source, TEntity obj,
bool
 isAnd) where TEntity : class
    
{
        
if (source == null)
            
throw new ArgumentNullException("Source can't be null!!");
        
//獲得所有property的信息
        PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public |
BindingFlags.Instance);

        Expression condition 
= null;
        
//先構(gòu)造了一個(gè)ParameterExpression對(duì)象,這里的c,就是Lambda表達(dá)中的參數(shù)。(c=>)  
        
//本變量被移出了foreach循環(huán)
        ParameterExpression param = Expression.Parameter(typeof(TEntity), "c");
        
//遍歷每個(gè)property
        foreach (PropertyInfo p in properties)
        
{
            
if (p != null)
            
{
                Type t 
= p.PropertyType;
                
//只支持value型和string型的影射
                if (t.IsValueType || t == typeof(string))
                
{
                    
//如果不為null才算做條件
                    if (p.GetValue(obj, null!= null)
                    
{
                        
//SQL Server does not support comparison of TEXT, NTEXT, XML and IMAGE ,etc
                        ///Only support BigInt,Bit,Char,Decimal,Money,NChar,Real,
                        
///Int,VarChar,SmallMoney,SmallInt,NVarChar,NVarChar(MAX),VarChar(MAX)

                        Attribute attr = Attribute.GetCustomAttribute(p, typeof(ColumnAttribute));
                        
if (attr != null)
                        
{
                            
string dbType = (attr as ColumnAttribute).DbType;
                            
if (dbType.Contains("Text"|| dbType.Contains("NText")
                                
|| dbType.Contains("Xml"|| dbType.Contains("Image")
                                
|| dbType.Contains("Binary"|| dbType.Contains("DateTime")
                                
|| dbType.Contains("sql_variant"|| dbType.Contains("rowversion")
                                
|| dbType.Contains("UniqueIdentifier"|| dbType.Contains
(
"VarBinary(MAX)"))
                            
{
                                
continue;
                            }

                        }
 
                        
//構(gòu)造表達(dá)式的右邊,值的一邊
                        Expression right = Expression.Constant(p.GetValue(obj, null), p.PropertyType);
                        
//構(gòu)造表達(dá)式的左邊,property一端。
                        Expression left = Expression.Property(param, p.Name);
                        
//生成篩選表達(dá)式。即c.CustomerID == "Tom"
                        Expression filter = Expression.Equal(left, right);
                        
if (condition == null)
                        
{
                            condition 
= filter;
                        }

                        
else
                        
{
                            
if (isAnd)
                                condition 
= Expression.And(condition, filter);
                            
else
                                condition 
= Expression.Or(condition, filter);
                        }

                    }

                }

            }

        }

        
if (condition != null)
        
{
            Expression
<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(condition, param);
            
return source.Where(pred);
        }
  
        
return source;
        
    }

    

系列文章導(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)查詢與保存log篇

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


在這里,首先檢查輸入的參數(shù)是否為null。擴(kuò)展方法其實(shí)是按靜態(tài)方法執(zhí)行的。它和靜態(tài)方法唯一不同的就是系統(tǒng)自動(dòng)為其加了一個(gè)Attribute,而這個(gè)Attribute只能通過(guò)在第一個(gè)參數(shù)加this關(guān)鍵字才能獲得。而后,在影射類型上,修改后的函數(shù)只支持?jǐn)?shù)值型和string型。其原因就是像imager等并不支持條件查詢。為了簡(jiǎn)化,我們只支持?jǐn)?shù)值型和string型。這里最大的變化莫過(guò)于支持or條件了。調(diào)用Expression.And或Expression.Or就可以了。還有一個(gè)變化就是ParameterExpression對(duì)象和Expression<Func<TEntity, bool>>被移出了foreach循環(huán)。這樣,提高了效率,只是在最后才去生成條件。
而實(shí)際上,大家大多使用是and條件,那再重載一個(gè)方法。

    public static IQueryable<TEntity> Find<TEntity>(this IQueryable<TEntity> source, TEntity obj) where TEntity : class
    
{
        
return Find<TEntity>(source,obj,true);
    }

系列文章導(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)查詢與保存log篇

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



2,限定字段在某集合中
這有點(diǎn)像in操作。比如where city in ('London', 'BeiJing') 也可以寫成 where city = 'London' or city = 'BeiJing'。既然談到or條件的動(dòng)態(tài)構(gòu)造了,那就也來(lái)構(gòu)造下這個(gè)吧。看上去有點(diǎn)多此一舉。但是,至少是個(gè)很好的學(xué)習(xí)機(jī)會(huì)。這個(gè)和上面不同的是,它條件字段是唯一的,變化的是該字段的值。那用一string將字段名成傳入,并用一集合將字段值傳入函數(shù)。
該函數(shù)完整的定義入下:


    
public static IQueryable<TEntity> WhereOr<TEntity, OrType>(this IQueryable<TEntity> source,
string
 propertyName, IEnumerable<OrType> values)
    
{
        
if (source == null)
            
throw new ArgumentNullException("Source can't be null!!");
        ParameterExpression param 
= Expression.Parameter(typeof(TEntity), "p");
        Expression left 
= Expression.Property(param, propertyName);
        Expression condition 
= null;
        
foreach (OrType value in values)
        
{
            Expression filter 
= Expression.Equal(left, Expression.Constant(value));
            
if (condition == null)
                condition 
= filter;
            
else
                condition 
= Expression.Or(condition,filter);
        }

        
if (condition != null)
            
return source.Where((Expression<Func<TEntity, bool>>)Expression.Lambda(condition,
param));

        
return source;
    }

系列文章導(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)查詢與保存log篇

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


3, CLR與SQL在某些細(xì)節(jié)上的差別
在上文中,有一朋友提出,其值不為null才做為條件,讓函數(shù)有局限性。既然提了,那筆者就再引申下。CLR與SQL中,對(duì)待null值是不同的。CLR認(rèn)為兩個(gè)null值是相等的,而SQL并不這么認(rèn)為。比如,下面的條件就是成立的。
        if (null == null)
            throw new Exception("CLR treat Null is the same!!");
但在Sql中只能判斷是不是null值,而不能對(duì)兩個(gè)字段的null值直接比較。
比如下面的語(yǔ)句
        var q6 = db.Employees.Where(c => c.Region == null).ToList();
翻譯為:

SELECT [t0].[EmployeeID][t0].[LastName][t0].[FirstName][t0].[Title][t0].
[TitleOfCourtesy][t0].[BirthDate][t0].[HireDate][t0].[Address][t0].[City
][t0].[Region][t0].[PostalCode][t0].[Country][t0].[HomePhone][t0].[Ext
ension
][t0].[Photo][t0].[Notes][t0].[ReportsTo][t0].[PhotoPath]
FROM [dbo].[Employees] AS [t0]
WHERE [t0].[Region] IS NULL

it知識(shí)庫(kù)Linq To Sql進(jìn)階系列(七)動(dòng)態(tài)查詢續(xù)及CLR與SQL在某些細(xì)節(jié)上的差別,轉(zhuǎn)載需保留來(lái)源!

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

主站蜘蛛池模板: 最新国产一区二区精品久久 | 亚洲另类激情小说 | 爽爽影院色黄网站在线观看 | 精品久久久久久综合日本 | 四虎最新永久在线精品免费 | 国产第一页在线视频 | 亚洲色图偷| 久久中文网中文字幕 | 国产网站视频 | 欧美日韩国产色综合一二三四 | 久久er国产精品免费观看2 | 一区二区高清在线观看 | 久久福利免费视频 | 中文字幕国产精品 | 色综合久久六月婷婷中文字幕 | 亚洲一区二区三区精品国产 | 国产精品video | 99在线观看视频免费精品9 | 久久99久久精品国产只有 | 91免费观看在线网址 | 亚洲爱 | 国产成人 免费观看 | 国产高颜值露脸在线观看 | 国产成人午夜精品免费视频 | 伊人激情视频 | 小说区乱图片区 | 久久综合图片 | 亚洲区色 | 国产成人91激情在线播放 | 久久99精品一级毛片 | 99ri精品国产亚洲 | 亚洲综合图片区 | 人人擦人人 | 高清国产激情视频在线观看 | 高清一区二区三区 | 狠狠亚洲婷婷综合色香五 | 在线免费精品视频 | 粉嫩粉嫩毛片视频 | 亚洲伊人久久大香线蕉苏妲己 | 黄网在线观看网址入口 | 91精品国产91热久久久久福利 |