(理論上)我們有以下查詢:
var variableDate = DateTime.Parse("Nov 2, 2021")
var results = (from x in db.FooBar
where x.Date == variableDate
select x).ToList();
我們可以簡單地將variableDate修改為 11/3/21、11/4/21 等,以回傳不同日期的結果。
問題是我們可以使用相同的查詢來回傳variableDate之后的 所有結果,并對運算子/變數進行一些修改嗎?例如,在variableDate 中包含運算子(> 或 ==)(我們稱之為variableDateFormula):
> 11/2/2021
或者
== 11/2/2021
這樣我們就可以簡單地使用相同的變數呼叫相同的查詢來回傳不同運算子的結果:
var results = (from x in db.FooBar
where x.Date variableDateFormula
select x).ToList();
我知道上面的建議不起作用,它只是為了可視化。我有一個查詢,它占用 9 行,根據傳遞給函式的 3 個值有 8 次不同的迭代。我很想避免撰寫基本相同的查詢 8 次并占用約 70 行,而是動態更改運算子/標準以僅包含 1 個查詢。
uj5u.com熱心網友回復:
是的,運算子只是函式呼叫的語法糖,您可以更改該函式,例如使用 lambda:
var equalFunc = ((d1,d2) => d1 == d2);
var greaterFunc = ((d1,d2) => DateTime.Compare(d1, d2) > 0);
var actualFunc = greaterFunc; // Insert logic here to choose the appropriate function
然后你的選擇變成
from x in db.FooBar
where actualFunc(x.Date, variableDate)
select x
uj5u.com熱心網友回復:
是的。LINQ 只是構建一個ExpressionTree物體框架將其轉換為 SQL,因此您可以使用其他運算式或 lambda 作為插入到樹中的引數,例如在這個 LINQpad 示例中:
void Main()
{
var aDate = new DateTime(2002, 1, 1);
GetResults(d => d.TheDate == aDate).Dump();
GetResults(d => d.TheDate <= aDate).Dump();
GetResults(d => d.TheDate > aDate).Dump();
}
IEnumerable<Data> GetResults(Func<Data, bool> op)
{
var data = new List<Data>
{
new Data{TheDate = new DateTime(2000,1,1)},
new Data{TheDate = new DateTime(2001,1,1)},
new Data{TheDate = new DateTime(2002,1,1)},
new Data{TheDate = new DateTime(2003,1,1)},
};
return data.Where(d => op(d));
}
public class Data
{
public DateTime TheDate { get; set; }
}
這會產生以下結果:

如果您在運算式中執行更復雜的邏輯,EF 資料庫提供程式可能無法將運算式轉換為 SQL。會有限制。例如,你不能這樣做:
GetResults(d => d.TheDate.ToString().Reverse() == "1234");
因為它不會理解自定義Reverse擴展方法。
uj5u.com熱心網友回復:
我建議將LINQKit用于此類任務。EF Core 無法將區域變數轉換為運算式函式。
var variableDate = DateTime.Parse("Nov 2, 2021");
Expression<Func<DateTime, DateTime, bool>> compareFunc = (d1, d2) => d1 > d2;
var results = (from x in db.FooBar
where compareFunc.Invoke(x.Date, variableDate)
select x).ToList();
要為 EF Core 啟用 LINQKit,請將以下內容添加到選項中:
builder
.UseSqlServer(connectionString)
.WithExpressionExpanding(); // enabling LINQKit extension
或者,如果您使用其他 LINQ 提供程式,請AsExpandable()在查詢頂部添加:
var results = (from x in db.FooBar.AsExpandable()
where compareFunc.Invoke(x.Date, variableDate)
select x).ToList();
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/345369.html
下一篇:根據事件的值按時間過濾事件
