(理论上)我们有以下查询:
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之后的所有结果/variable,并对操作符/variable(S)进行一些修改?例如,将操作符(>或==)包含在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行,而是动态地更改操作符/条件,使其只有一个查询。
发布于 2021-11-02 13:58:23
是的,运算符只是函数调用的语法糖,您可以更改该函数,例如使用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发布于 2021-11-02 14:01:23
是。LINQ只是构建实体框架转换为SQL的ExpressionTree,因此您可以使用其他表达式或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扩展方法。
发布于 2021-11-02 15:29:30
我建议使用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启用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://stackoverflow.com/questions/69811518
复制相似问题