简体   繁体   English

如何组合两个 LINQ select 表达式?

[英]How can I combine two LINQ select expressions?

I am trying to have a select expression that can be incrementally updated depending on what I receive from the input, something like this:我试图有一个 select 表达式,可以根据我从输入中收到的内容进行增量更新,如下所示:

// Init expression
Expression<Func<Order, object>> selectExpression = x => new
{
    x.Id
};

if(selectInput.Title){
    // something like this
    selectExpression = selectExpression.Add(x => new
    {
        x.Title
    });
}
if(selectInput.ClientFullName){
    // something like this
    selectExpression = selectExpression.Add(x => new
    {
        ClientFullname = x.Client.Fullname
    });
}

// Use expression in a LINQ query (for an EF Core query)
var result = await queryable.Select(selectExpression).ToListAsync();

Then I would expect to have a result like this然后我希望有这样的结果

{
    "Id": 568,
    "Title": "Order 567",
    "ClientFullname": "John Smith"
}

Is this something that is possible?这是可能的吗? The only examples I found online are about.Where().我在网上找到的唯一例子是 about.Where()。 Am I going into the wrong direction?我走错方向了吗?

Thank you!谢谢!

If you would do this, then the problem is, that your compiler would not know whether property ClientFullName is a property in your result or not, thus your compiler can't use it.如果您这样做,那么问题是,您的编译器将不知道属性ClientFullName是否是结果中的属性,因此您的编译器无法使用它。

Of course you can use the name of the property as an identifier, and put everything in a Dictionary.当然,您可以使用属性的名称作为标识符,并将所有内容放入字典中。 like @Canton7 suggested.就像@Canton7 建议的那样。

If you don't expect null values, you can return a class with all properties.如果您不期望 null 值,则可以返回具有所有属性的 class。 The properties that have value null will not have been selected:将不会选择具有值 null 的属性:

class MyItem
{
    public int Id {get; set;}              // Id always fetched
    public string Title {get; set;}
    public DateTime? Date {get; set;}
    ... // etc: all nullable properties
}

As an extension method:作为扩展方法:

public static IQueryable<MyItem> ToSelectedItems(
    this IQueryable<Order> orders,
    SelectedInput selectedInput)
{
    // TODO: exception if orders or selectedInput null

    return orders.Select(order => new MyItem
    {
        Id = order.Id,

        // properties null if not in selectedInput
        Title = selectedInput.Title ? order.Title : null,
        ClientFullName = selectedInput.ClientFullName ? order.ClientFullName : null,
        Date = selectedInput.Date ? order.Date : null,
     })

You might find LinqKit useful: ( http://www.albahari.com/nutshell/linqkit.aspx ) I have used this many times when trying to write variable where clauses against IQueryable data sources.您可能会发现 LinqKit 很有用:( http://www.albahari.com/nutshell/linqkit.aspx )在尝试针对 IQueryable 数据源编写变量 where 子句时,我已经使用了很多次。 The PredicateBuilder ( http://www.albahari.com/nutshell/predicatebuilder.aspx ) is really useful for constructing dynamic query expressions. PredicateBuilder ( http://www.albahari.com/nutshell/predicatebuilder.aspx ) 对于构建动态查询表达式非常有用。

Sample code would be something like this...示例代码将是这样的......

    public void QueryItems(string id, string name, string fullname)
    {
        // this would be the collection od data to be filtered
        var items = new List<Item>();

        // initialise predicate of for querying objects of type Item
        var predicate = PredicateBuilder.New<Item>();

        // dynamically add clauses dependent on available filter values
        if (!string.IsNullOrEmpty(id))
        {
            predicate = predicate.And(x => x.Id == id);
        }
        if (!string.IsNullOrEmpty(name))
        {
            predicate = predicate.And(x => x.Name == name);
        }
        if(!string.IsNullOrEmpty(fullname))
        {
            predicate = predicate.And(x => x.FullName == fullname);
        }

        // evaluate the result of the dynamic query
        var result = items.Where(predicate).ToList();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM