EF Core 和 LINQ - 如何在 运行 时间使用字符串变量构建动态 Where 子句?

EF Core & LINQ - How to build a dynamic Where clause using a string variable at run time?

我读过很多关于这个问题的变体,我无法相信我需要的解决方案是如此复杂以至于需要使用额外的库和疯狂的技巧,但愿不会!

在 运行 时,我的项目中的 LINQ 查询需要动态更改,具体取决于用户要作为过滤依据的数据库 table 中的列数。在我的示例中,我首先展示了一个硬编码的有效 LINQ 查询。 下一个示例使用在 运行 时构建的列表,我需要弄清楚的是如何将字符串变量 (whereClause) 插入到 LINQ 查询中而不会出现编译错误?

工作示例(硬编码)

logs = _context.Logs.Where(s => s.Level == LogLevel & s.LogEventCategory == EventCategory)
               .Select(s => new Logs()
               {
                   TimeStamp = s.TimeStamp,
                   Level = s.Level,
                   Exception = s.Exception,
                   LogEventCategory = s.LogEventCategory,
                   LogEventType = s.LogEventType,
                   LogEventSource = s.LogEventSource,
                   LogEventName = s.LogEventName,
                   LogUserName = s.LogUserName,
                   LogForename = s.LogForename,
                   LogSurname = s.LogSurname,
                   LogData = s.LogData
               });

示例二 - 我想修复和使用的解决方案...

首先创建一个列表,每次新的查询都会改变列表的内容运行,通过父OnGet方法作为变量传递的字符串将包含一个值并在字符串连接中使用串联,或将为空,因此不会添加到列表中并在串联中使用。

第二个例子是我遇到编译错误的地方。

var filtersList = new List<string>();
        if (LogLevel != null)
        {
            filtersList.Add("s.LogLevel == LogLevel");
        }
        if (EventCategory != null)
        {
            filtersList.Add("s.EventCategory == EventCategory");
        }

        var whereClause = string.Join(" & ", filtersList.ToArray());


logs = _context.Logs.Where(s => whereClause) // *HERE I WANT TO USE THE STRING VARIABLE! not working
                   .Select(s => new Logs()
                   {
                       TimeStamp = s.TimeStamp,
                       Level = s.Level,
                       Exception = s.Exception,
                       LogEventCategory = s.LogEventCategory,
                       LogEventType = s.LogEventType,
                       LogEventSource = s.LogEventSource,
                       LogEventName = s.LogEventName,
                       LogUserName = s.LogUserName,
                       LogForename = s.LogForename,
                       LogSurname = s.LogSurname,
                       LogData = s.LogData
                   });

我得到的错误是 'Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type' blah blah blah

您只需在具体化之前将 .Where() 调用添加到查询的末尾:

query = _context.Logs.Select(s => new ..);

if (EventCategory != null) query = query.Where(e => e.EventCategory == EventCategory);
if (LogLevel != null) query = query.Where(e => e.LogLevel == LogLevel);

var items = query.ToList();