中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linq to sql動態查詢的方法有哪些

發布時間:2021-12-01 16:06:56 來源:億速云 閱讀:220 作者:iii 欄目:編程語言

這篇文章主要講解了“Linq to sql動態查詢的方法有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Linq to sql動態查詢的方法有哪些”吧!

1,Linq to sql動態查詢之用object的查詢是什么?

我們可以簡單的舉這么一個例子。我們到公安局查找一個人。首先,我們會給出他的一些特征,比如,身高多少,年齡多少,性別,民族等。那么,我們把這個人的一些特征輸入電腦。我們希望,電腦能給我們返回這個人的信息。

而實際上,有相同特征的人太多了,常常返回一個集合。那讓我們把這個過程抽象到程式里。我們需要new出來一個對象。這個對象包含了我們能知道的基本信息。而后,把這個對象傳給Linq To Sql,等待返回結果。

根據這些基本的需求,我們來定義下面的函數,為了實現這個函數對任何實體都是有用的,我們把它定義為generic的。為了不破壞Linq To Sql延遲加載的規矩,我們把它的返回類型定義為IQueryable。如下:

public IQueryableFind(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動態查詢之原理

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條件。  queryquery = query.Where(pred);

3,Linq to sql動態查詢之反射在本方法中的作用

因為我們采用了模板,也就是說,我們并不知道傳進來的對象會有那些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);  queryquery = query.Where(pred);  }  }  }  }  return query;  }

4,Linq to sql動態查詢之測試用例及反思

我們用下面的例子來測試下這個函數

Customer c = new Customer();  c.City = "London";  c.Phone = "23236133";  var q = db.Find<Customer>(c).ToList();

其生成的sql語句為:

SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]  FROM [dbo].[Customers] AS [t0]  WHERE ([t0].[Phone] = @p0) AND ([t0].[City] = @p1)  -- @p0: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [23236133]  -- @p1: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]

我們可以看到,其Linq to sql動態查詢語句中,只有city和phone兩個條件。并且他們之間是and的關系。我們最開始的設想實現了,但是,它是***的嗎?如果是or條件該怎么辦呢?更多的時候,我們是在用模糊查詢,那又該怎么辦呢?這個問題,就留于下篇。

***,介紹一種寫log的方法。stream流使用static為避免多個datacontext的同時在使用log.txt文件。

  partial class DataMappingDataContext  {  private static StreamWriter sw = new StreamWriter(Path.Combine(Directory.GetCurrentDirectory(), "log.txt"),true);  /**//// <summary> /// Try to create DataContext with log.  /// summary> /// <param name="withLog">param> public DataMappingDataContext(bool withLog)  : this()  {  OnCreated();  if (withLog)  {  if (sw == null)  {  sw = new StreamWriter(Path.Combine(Directory.GetCurrentDirectory(), "log.txt"), true);  }  this.Log = sw;  }  }  /**//// <summary> /// try to close streamwriter  /// summary> /// <param name="disposing">param>         protected override void Dispose(bool disposing)  {  base.Dispose(disposing);  sw.Flush();  }  }    在dispose函數里,把輸出流flush。使用時,如下  using(northwind db = new norhwind(true))  {  //do something......  }

感謝各位的閱讀,以上就是“Linq to sql動態查詢的方法有哪些”的內容了,經過本文的學習后,相信大家對Linq to sql動態查詢的方法有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

芦山县| 黄梅县| 北海市| 班玛县| 屯昌县| 鞍山市| 乌兰浩特市| 牙克石市| 达拉特旗| 和平区| 石台县| 昭觉县| 拜泉县| 昭平县| 牡丹江市| 革吉县| 静乐县| 桑植县| 托克逊县| 高要市| 海南省| 镇巴县| 纳雍县| 申扎县| 合水县| 万宁市| 衡东县| 鄢陵县| 博兴县| 德清县| 南投市| 惠来县| 南皮县| 丘北县| 佳木斯市| 丰镇市| 利川市| 沙河市| 万年县| 布尔津县| 双峰县|