如何存储 linq 查询?

Posted

技术标签:

【中文标题】如何存储 linq 查询?【英文标题】:How can I store linq queries? 【发布时间】:2021-06-08 09:39:13 【问题描述】:

我进行了研究,但没有发现任何关于这种情况的信息。

我有两个 linq 查询:

            //checking all columns if there is
            mockDataList = mockDataList.Where(w =>
            w.Email.ToLower().Contains(search)          ||
            w.Gender.ToLower().Contains(search)         ||
            w.Name.ToLower().Contains(search)           ||
            w.Surname.ToLower().Contains(search)        ||
            w.Id.ToString().ToLower().Contains(search)
            ).Skip(start).Take(length).ToList();

            //getting count info
            var filteredTotal = mockDataList.Where(w =>
            w.Email.ToLower().Contains(search) ||
            w.Gender.ToLower().Contains(search) ||
            w.Name.ToLower().Contains(search) ||
            w.Surname.ToLower().Contains(search) ||
            w.Id.ToString().ToLower().Contains(search)
            ).Count();

我想先数一下,取其中的 10 个。因此我不得不写两个查询。我不希望它重复。不执行查询如何存储?

*抱歉我的语法错误

【问题讨论】:

【参考方案1】:

当您通过foreach 循环通过它们或调用FirstOrDefault()ToList()ToArray() 等方法时,将执行LINQ 查询...所以以下是没问题的:

var query = mockDataList.Where(w =>
            w.Email.ToLower().Contains(search)          ||
            w.Gender.ToLower().Contains(search)         ||
            w.Name.ToLower().Contains(search)           ||
            w.Surname.ToLower().Contains(search)        ||
            w.Id.ToString().ToLower().Contains(search)
            ); // nothing is done here, no filtering

mockDataList  = query.Skip(start).Take(length).ToList(); // here, the filtering is done
var filteredTotal = query.Count(); // here, the filtering is done again

【讨论】:

你引入了一个错误 ;) 应该在分页之前计算计数。闭包。 @SvyatoslavDanyliv 我检查了代码,很抱歉,但我真的没有看到这里有问题。你能详细说明一下这个问题吗? 我敢打赌他是用它来做页面摘要什么的。跳过后的计数不会像他以前那样代表所需查询中的总项目数。 @Delsx:至少在这个例子中它有效:dotnetfiddle.net/WYEpwP 感谢@SomeBody,我认为linq 查询是直接执行的【参考方案2】:

只需将 LINQ 查询存储在局部变量中:

var query = mockDataList.Where(w =>
            w.Email.ToLower().Contains(search) ||
            w.Gender.ToLower().Contains(search) ||
            w.Name.ToLower().Contains(search) ||
            w.Surname.ToLower().Contains(search) ||
            w.Id.ToString().ToLower().Contains(search));

var filteredTotal = query.Count();

mockDataList = query.Skip(start).Take(length).ToList();

【讨论】:

【参考方案3】:

我认为更好的做法是按照@SomeBody 的建议存储 IEnumerable。

IEnumerable<MyClass> query = mockDataList.Where(w => .....);
List<MyClass> PaginatedFilteredItems = query.Skip(start).Take(length).ToList();
int FilteredItemsTotal = query.Count();
// Or
int PaginatedFilteredItemsTotal = PaginatedFilteredItems.Count;

另一种方法是使用 Func 或 Expression 来存储您的查询:

public class MyClass
    public int Id;
    public string Email;
    public string Gender;
    public string Name;
    public string Surname;  


Func<MyClass, bool> MyClassFunc = w =>
            w.Email.ToLower().Contains(search)          ||
            w.Gender.ToLower().Contains(search)         ||
            w.Name.ToLower().Contains(search)           ||
            w.Surname.ToLower().Contains(search)        ||
            w.Id.ToString().ToLower().Contains(search);

那么你可以这样使用它:

mockDataList = mockDataList.Where(MyClassFunc).Skip(start).Take(length).ToList();

【讨论】:

以上是关于如何存储 linq 查询?的主要内容,如果未能解决你的问题,请参考以下文章

将数组存储为逗号分隔,如何使用 LINQ 进行查询?

如何针对分层对象列表动态构建和存储复杂的 linq 查询?

如何向本地存储帐户中的表编写 LINQ 查询?

LINQ to SQL 将查询结果存储在变量中

如何编写这个 Linq-to-SQL 选择查询

如何编写此 LINQ 查询的 SQL 版本?