首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >作为变量的C# linq算子

作为变量的C# linq算子
EN

Stack Overflow用户
提问于 2021-11-02 13:43:40
回答 3查看 239关注 0票数 0

(理论上)我们有以下查询:

代码语言:javascript
复制
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

这样,我们就可以使用相同的变量调用相同的查询来返回不同运算符的结果:

代码语言:javascript
复制
var results = (from x in db.FooBar
               where x.Date variableDateFormula 
               select x).ToList();

我知道上面的建议是行不通的,它只是为了可视化。我有一个查询,它占用9行,并根据传递到函数的3个值进行8次不同的迭代。我希望避免编写8次基本相同的查询,占用大约70行,而是动态地更改操作符/条件,使其只有一个查询。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-11-02 13:58:23

是的,运算符只是函数调用的语法糖,您可以更改该函数,例如使用lambda:

代码语言:javascript
复制
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

然后你的选择变成

代码语言:javascript
复制
from x in db.FooBar
where actualFunc(x.Date, variableDate)
select x
票数 2
EN

Stack Overflow用户

发布于 2021-11-02 14:01:23

是。LINQ只是构建实体框架转换为SQL的ExpressionTree,因此您可以使用其他表达式或lambda作为插入到树中的参数,如下面的LINQpad示例:

代码语言:javascript
复制
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。会有局限性的。例如,你不能这样做:

代码语言:javascript
复制
GetResults(d => d.TheDate.ToString().Reverse() == "1234");

因为它不理解定制的Reverse扩展方法。

票数 0
EN

Stack Overflow用户

发布于 2021-11-02 15:29:30

我建议使用LINQKit来完成这样的任务。EF Core不能将局部变量转换为表达式函数。

代码语言:javascript
复制
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,在选项中添加以下内容:

代码语言:javascript
复制
builder
    .UseSqlServer(connectionString)
    .WithExpressionExpanding(); // enabling LINQKit extension

或者,如果使用其他LINQ提供程序,则在查询的顶部添加AsExpandable()

代码语言:javascript
复制
var results = (from x in db.FooBar.AsExpandable()
               where compareFunc.Invoke(x.Date, variableDate)
               select x).ToList();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69811518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档