用lambda構建ORM查詢語句

2021-08-26 21:13:56 字數 2884 閱讀 6499

本文介紹如何解析lambda表示式來獲取乙個滿足條件的查詢語句。

先看個截圖

通過設定實體物件article_content的查詢表示式,就可以獲取對應的引數化sql語句,使用起來很方便,減少了**的書寫,同時提高了安全性。

本文需要了解的基礎知識有:

lambda表示式

expression表示式樹

擴充套件方法

首先,我們應該有乙個普通的實體物件和它的基類

//基類

class baseentity

//實體物件

class article_content : baseentity

public

string article_title

public

string article_sourceurl

}

這個時候我們需要定義一些擴充套件方法以便對實體的查詢表示式進行儲存。我們的sql語句的需求是要引數化的。所以,在實體物件這裡還不知道資料庫型別,沒有辦法獲取對應的引數化符號。

/// 

/// 設定匹配表示式

///

public

static

void setwherefunc(this t entity, expressionbool>> func) where t : baseentity

好了。這個時候我們可以寫出類似下面的**了:
article_content art = new article_content();

art.setwherefunc(ar=>ar.aritlce_id == 4 && ar.article_title == "sss");

但是sql語句中很常見的like查詢似乎還沒有辦法實現。

我們通過分析where子句,發現where語句的做事然篩選出來的紀錄要滿足where子句的條件,那麼where子句返回的就是乙個bool,where子句其實是乙個邏輯表示式。所以,就有了剛才setwherefunc函式裡面的第二個引數中func的返回值是bool。

既然where子句要求返回的是乙個bool表示式同理:like、in、not等表達方法我們也只能讓它返回的是bool值;

那麼就有了下面的擴充套件函式:

public

static

bool in(this t obj, t array)

public

static

bool like(this

string str, string likestr)

這個時候很現在,我們的setwherefunc可以寫出如下的**了:

art.setwherefunc(ar=>ar.aritlce_id.in(new

int?) && ar.article_title.like("%sss"));

到目前為止,前台編寫方式已經解決了。
剩下的就是如何來分析我們設定的這個lambda表示式了。
當然分析lambda表示式的時候,我們還需要考慮生成的sql語句的引數化。這個時候還需要另乙個資料操作物件:
public

abstract

class dboperate

這個物件還有其他方法,不過在這裡,我們主要使用的就是這樣乙個引數標識,如果它在mssql裡,它返回的是@+fieldname,orcale則返回的是:fieldname。

在構建sql語句的時候,我們同樣也使用擴充套件方法來解析表示式。

internal

static

string where(this t entity, expression func, dboperate dbop, ref arraylist alparamnames, ref arraylist alparamvalues) where t : baseentity

lambda表示式也是表示式的一種。那麼我們可以通過分析表示式的型別計算對應的產生式。
現在主要遇到的表示式有以下幾種:
binaryexpression

lambdaexpression

methodcallexpression

memberexpression

constantexpression

newarrayexpression

unaryexpression

根據不同的型別,可以進行不同操作,為了簡單起見,我們這裡演示的是直接拼接字串的方式,各位可以自己嘗試使用引數的方式,函式原型在上面了。

到這裡,乙個基於表示式分析的實體查詢就做好了。

下面是文章一開始的那個lambda表示式分析出來的對應的where語句

對應的引數和引數值順序是一一對應的。

我這裡的對expression表示式進行了計算,所以最後乙個引數對應的

string.concat(getstr(7), "sdfsdf".length, "sssss" + getstr(6)).toupper()
這個表示式已經被計算完成得到"good76sssssgood6",getstr(int)函式見第一張截圖。

這裡主要體會的是用expression tree的乙個實際用法。實際跑起來體會下就能明白。要說的話實在內容太多。而前面的都介紹都是概念性的.

什麼是ORM 為啥要是用ORM?

了解orm,先了解以下概念 什麼是 持久化 持久 persistence 即把資料 如記憶體中的物件 儲存到可永久儲存的儲存裝置中 如磁碟 持久化的主要應用是將記憶體中的資料儲存在關係型的資料庫中,當然也可以儲存在磁碟檔案中 xml資料檔案中等等。什麼是 持久層 持久層 persistence la...

orm的增刪改查

orm增加字段 phone models.charfield max length 64,default 120 後來新增的字段需要設定預設值 orm刪除字段 注釋掉字段,執行資料庫遷移命令 慎重 修改字段 直接修改字段,執行資料庫遷移命令 單錶查詢 res models.user.objects....

orm簡單的增刪改查

類 type user struct增加 插入 1.有orm物件 o orm.neworm 2.有乙個插入資料的結構體物件 user models.user 3.對結構體賦值 user.name 111 user.pwd 222 4.插入 err o.insert user if err nil刪除...