Linq查询存储为字符串和/或序列化为Json

时间:2019-04-27 07:57:20

标签: c# linq asp.net-core-2.2

具有给定的对象列表,例如

public List<Event> itemList { get; set; }

我喜欢这样查询它

var newItemList = itemList
                  .Where(l => l.Published && l.PublishStart <= DateTime.Today)
                  .OrderBy(l => l.PublishStart)
                  .ToList();

现在,我需要能够进行多个查询并从

开始
List<Event> newItemList;

if (EventType.Equals("consert"))
{
    newItemList = itemList
                  .Where(l => l.Published && l.PublishType == EventType.Consert)
                  .OrderBy(l => l.PublishStart)
                  .ToList();
}
else if (EventType.Equals("last-chance"))
{
    newItemList = itemList
                  .Where(l => l.Published)
                  .OrderBy(l => l.PublishEnd)
                  .ToList();
}
// and so on...

请注意,这些示例已简化/缩短


随着上述内容变得越来越长,并且稍微简化了代码,是否可以将查询存储为字符串和/或序列化为Json,并执行类似的操作?

    var query_where = "l => l.Published && l.PublishType == EventType.Consert";
    var query_orderby = "l => l.PublishStart";

    newItemList = itemList
                  .Where(query_where)
                  .OrderBy(query_orderby)
                  .ToList();

如上所述,我意识到它可能不是类型安全的,但是,我确实确实需要以一种或另一种方式对它进行字符串化或序列化,以便可以将其动态添加到解决方案中。

2 个答案:

答案 0 :(得分:1)

您可以使用方法来做到这一点,例如:

private bool IsEventPublishedConcert(Event l) => l.Published && l.PublishType == EventType.Consert;
private DateTime GetEventStartTime(Event l) => l.StartTime;


newItemList = itemList
              .Where(IsEventPublishedConcert)
              .OrderBy(GetEventStartTime)
              .ToList();

答案 1 :(得分:1)

是的,您可以使用nuget软件包System.Dynamic.Linq.Core

    var where = "";
    var ordering = "";

    if (eventType.Equals("consert"))
    {
        where = "Published and PublishType =\"Consert\"";
        ordering = "PublishStart";

    }
    else if (eventType.Equals("last-chance"))
    {
        where = "Published";
        ordering = "PublishEnd";
    }

    newItemList = itemList.AsQueryable() // this is in order to enable Dynamic.Linq
        .Where(where)
        .OrderBy(ordering)
        .ToList();   

但是,正如其他人指出的那样,由于IEnumerable接口是可组合的,因此您可以决定在Where子句中放置什么而无需实际运行它们的方式。

    IEnumerable<Event> newItems = itemList;

    if (eventType.Equals("consert"))
    {
        newItems = newItems.Where(c => c.Published && c.PublishType == EventType.Consert);
    }
    else if (eventType.Equals("last-chance"))
    {
        newItems = newItems.Where(c => c.Published);
    }


    if (eventType.Equals("consert"))
    {
        newItems = newItems.OrderBy(c => c.PublishStart);
    }
    else if (eventType.Equals("last-chance"))
    {
        newItems = newItems.OrderBy(c => c.PublishEnd);
    }

    var newItemsList = newItems.ToList(); // newItems holds references to the expressions and the .ToList() call will parse and execute them at this moment

这种重复可能很烦人,因此您还可以选择使用Func

    IEnumerable<Event> newItems = itemList;
    Func<Event, DateTime> orderBy = null;

    if (eventType.Equals("consert"))
    {
        newItems = newItems.Where(c => c.Published && c.PublishType == EventType.Consert);
        orderBy = c => c.PublishStart;

    }
    else if (eventType.Equals("last-chance"))
    {
        newItems = newItems.Where(c => c.Published);
        orderBy = c => c.PublishEnd;

    }

    if (orderBy != null)
    {
        newItems = newItems.OrderBy(orderBy);
    }


    var newItemsList = newItems.ToList(); // newItems holds references to the expressions and the .ToList() call will parse and execute them at this moment