简体   繁体   English

如何将 2 选择减少到 1 选择 linq 以获得性能?

[英]how can I reduce 2 select to 1 select linq to gain performance?

my question is simple but I got stuck with something.我的问题很简单,但我遇到了一些问题。 Can you tell me how can I reduce 2 select into 1 select LINQ in c#?你能告诉我如何在 c# 中将 2 个选择减少为 1 个选择 LINQ? I am using CloudNative.CloudEvents NuGet package for cloud-native events.我正在为云原生事件使用 CloudNative.CloudEvents NuGet 包。

var orderEvents = input
    .Select(_ => new OrderDocument(_.Id, _.ToString()).ToOrderEvent())
    .Select(_ =>
        new CloudEvent()
        {
            Type = _.EventType,
            Subject = _.Subject,
            Source = _.Source,
            Data = _
        });

input is a parameter from cosmosDbTrigger it`s type : IReadOnlyList输入是 cosmosDbTrigger 的参数,它的类型:IReadOnlyList

OrderDocument.cs订单文档.cs

public class OrderDocument
{
    public string Id { get; private set; }

    public string Json { get; private set; }

    public OrderDocument(string id, string json)
    {
        Id = id;
        Json = json;
    }

    public OrderEvent ToOrderEvent() => OrderEventHelper.ToOrderEvent(Json);
}

OrderEventHelper.cs OrderEventHelper.cs

public static OrderEvent ToOrderEvent(string json)
{
    ArgumentHelper.ThrowIfNullOrEmpty(json);

    var orderEvent = JsonConvert.DeserializeObject<OrderEvent>(json);
    var eventDefinition = OrderEvents.EventDefinitions.SingleOrDefault(_ => _.EventType == orderEvent.EventType);

    
    return eventDefinition == null
        ? orderEvent
        : new OrderEvent(
            orderEvent.Id,
            orderEvent.Source,
            orderEvent.EventType,
            orderEvent.Subject,
            orderEvent.DataContentType,
            orderEvent.DataSchema,
            orderEvent.Timestamp,
            JsonConvert.DeserializeObject(orderEvent.Payload.ToString(), eventDefinition.PayloadType),
            orderEvent.TraceId);

}

linq extensions are basically for loops in the background. linq 扩展基本上是在后台循环。 If you want to perform multiple actions against a list, perhaps making your own simple for loop where you can manage that yourself would work.如果您想对一个列表执行多个操作,也许可以制作自己的简单 for 循环,您可以自己管理它。

Your code:你的代码:

var orderEvents = input
    .Select(_ => new OrderDocument(_.Id, _.ToString()).ToOrderEvent())
    .Select(_ =>
        new CloudEvent()
        {
            Type = _.EventType,
            Subject = _.Subject,
            Source = _.Source,
            Data = _
        });

could be changed to:可以改为:

// our result set, rather than the one returned from linq Select
var results = new List<CloudEvent>();

foreach(var x in input){
   // create the order event here
   var temporaryOrderEvent = new OrderDocument(x.Id, x.ToString()).ToOrderEvent();
   
   // add the Cloud event to our result set
   results.Add(new CloudEvent() 
   {
       Type = temporaryOrderEvent .EventType,
       Subject = temporaryOrderEvent .Subject,
       Source = temporaryOrderEvent .Source,
       Data = temporaryOrderEvent 
   });
}

where you then have a result list to work with.然后您可以在其中使用result列表。

If you wanted to keep it all in linq, you could instead perform all of your logic in the first Select , and ensure that it returns a CloudEvent .如果您想将其全部保存在 linq 中,则可以改为在第一个Select中执行所有逻辑,并确保它返回CloudEvent Notice here that you can employ the use of curly brackets in the linq statement to evaluate a function rather than a single variable value:请注意,您可以在 linq 语句中使用大括号来评估函数而不是单个变量值:

var orderEvents = input
    .Select(x => 
    {
       // create the order event here
       var temporaryOrderEvent = new OrderDocument(x.Id, x.ToString()).ToOrderEvent();

       // return the Cloud event here
       return new CloudEvent() 
                  {
                       Type = temporaryOrderEvent .EventType,
                       Subject = temporaryOrderEvent .Subject,
                       Source = temporaryOrderEvent .Source,
                       Data = temporaryOrderEvent 
                  };
    });

How about putting conversion to OrderEvent and using ToCloudEvent in the same Select?将转换为 OrderEvent 并在同一个 Select 中使用 ToCloudEvent 怎么样?

var orderEvents = input
    .Select(_ => new OrderDocument(_.Id, _.ToString()).ToOrderEvent().ToCloudEvent())


public class OrderEvent
{
    public CloudEvent ToCloudEvent()
    {
        new CloudEvent()
        {
            Type = this.EventType,
            Subject = this.Subject,
            Source = this.Source,
            Data = this
        };
    }
}

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

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