C如何对动态类型和字符串执行比较运算符

C# 如何对动态类型和字符串执行比较运算符

问题描述

我有两个绑定到以下模型的HTTP请求:

    public class ShopifyAPI
{
    public class ShopifyAPIAuth
    {
        [Required]
        public required string AccessToken { get; set; }

        [Required]
        public required string Key { get; set; }

        [Required]
        public required string Secret { get; set; }
    }


    public class ShopifyOrderResponse
    {
        [Required]
        [JsonPropertyName("orders")]
        public required List<ShopifyOrder>? Orders { get; set; }
    }

    public class ShopifyOrder
    {
        [Required]
        [JsonPropertyName("id")]
        public long Id { get; set; }

        [Required]
        [JsonPropertyName("order_number")]
        public required long OrderNumber { get; set; }

        [Required]
        [JsonPropertyName("financial_status")]
        public required string PaymentStatus { get; set; }

        [Required]
        [JsonPropertyName("shipping_address")]
        public required Address ShippingAddress { get; set; }

        [Required]
        [JsonPropertyName("billing_address")]
        public required Address BillingAddress { get; set; }

        [Required]
        [JsonPropertyName("line_items")]
        public required List<Product> Products { get; set; }

    }

    public class Address
    {
        [Required]
        [JsonPropertyName("first_name")]
        public required string FirstName { get; set; }

        [Required]
        [JsonPropertyName("last_name")]
        public required string LastName { get; set; }

        [Required]
        [JsonPropertyName("address1")]
        public required string Address1 { get; set; }

        [JsonPropertyName("address2")]
        public string? Address2 { get; set; }

        [Required]
        [JsonPropertyName("city")]
        public required string City { get; set; }

        [Required]
        [JsonPropertyName("province")]
        public required string State { get; set; }

        [Required]
        [JsonPropertyName("zip")]
        public required string Zipcode { get; set; }

        [Required]
        [JsonPropertyName("country")]
        public required string Country { get; set; }

        [JsonPropertyName("phone")]
        public string? Phone { get; set; }
    }

    public class Product
    {
        [JsonPropertyName("product_id")]
        public long? Id { get; set; }

        [JsonPropertyName("title")]
        public string? ProductName { get; set; }

        [JsonPropertyName("variant_id")]
        public long? VariationId { get; set; }

        [JsonPropertyName("variant_title")]
        public string? VariationName { get; set; }

        [JsonPropertyName("quantity")]
        public long? Quantity { get; set; }
    }
}

public class WoocommerceAPI
{
    public class WoocommerceAPIAuth
    {
        [Required]
        public required string Key { get; set; }

        [Required]
        public required string Secret { get; set; }
    }

    public class WoocommerceOrder
    {
        [Required]
        [JsonPropertyName("id")]
        public long Id { get; set; }

        [Required]
        [JsonPropertyName("status")]
        public required string Status { get; set; }

        [Required]
        [JsonPropertyName("shipping")]
        public required Address ShippingAddress { get; set; }

        [Required]
        [JsonPropertyName("billing")]
        public required Address BillingAddress { get; set; }

        [Required]
        [JsonPropertyName("line_items")]
        public required List<Product> Products { get; set; }

        [Required]
        [JsonPropertyName("meta_data")]
        public required List<MetaData> MetaDatas { get; set; }

    }

    public class Address
    {
        [Required]
        [JsonPropertyName("first_name")]
        public required string FirstName { get; set; }

        [Required]
        [JsonPropertyName("last_name")]
        public required string LastName { get; set; }

        [Required]
        [JsonPropertyName("address_1")]
        public required string Address1 { get; set; }

        [JsonPropertyName("address_2")]
        public string? Address2 { get; set; }

        [Required]
        [JsonPropertyName("city")]
        public required string City { get; set; }

        [Required]
        [JsonPropertyName("state")]
        public required string State { get; set; }

        [Required]
        [JsonPropertyName("postcode")]
        public required string Zipcode { get; set; }

        [Required]
        [JsonPropertyName("country")]
        public required string Country { get; set; }

        [JsonPropertyName("phone")]
        public string? Phone { get; set; }
    }

    public class Product
    {
        [JsonPropertyName("product_id")]
        public long? Id { get; set; }

        [JsonPropertyName("name")]
        public string? ProductName { get; set; }

        [JsonPropertyName("variation_id")]
        public long? VariationId { get; set; }

        [JsonPropertyName("quantity")]
        public long? Quantity { get; set; }
    }

    public class MetaData
    {
        [Required]
        [JsonPropertyName("id")]
        public required dynamic Id { get; set; }

        [Required]
        [JsonPropertyName("key")]
        public required dynamic Key { get; set; }

        [Required]
        [JsonPropertyName("value")]
        public required dynamic Value { get; set; }

    }
}

我在以下控制器中使用这些模型:

    [HttpPost(Name = "PostDataExport")]
    [EnableRateLimiting("api")]
    public async Task<IActionResult> Post()
    {
        Task<List<ShopifyOrder>> importShopifyOrders = _shopifyService.GetOrders("https://dirtdudesutv.myshopify.com", _shopifyAPIAuth.AccessToken);
        Task<List<WoocommerceOrder>> importWoocommerceOrders = _woocommerceService.GetOrders("https://www.aaaprintco.com", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_woocommerceAPIAuth.Key}:{_woocommerceAPIAuth.Secret}")));

        List<Task> tasks = new List<Task> { importShopifyOrders, importWoocommerceOrders };
        await Task.WhenAll(tasks);

        foreach (var order in importShopifyOrders.Result)
        {
            bool alreadyImportedOrder = importWoocommerceOrders.Result.Any(o => o.MetaDatas.Any(m =>(m.Key == "_shopify_order_id" && m.Value.ToString() == order.Id.ToString())));

            if(alreadyImportedOrder)
            {
                importShopifyOrders.Result.Remove(order);
            }
        }

        return Ok(importWoocommerceOrders.Result);
    }
}

这个控制器的目的是将所有Shopify订单和所有WooCommerce订单拉取出来。然后我需要找出哪些Shopify订单已经在WooCommerce订单中,如果订单存在于foreach循环中所显示的那样,那么就将其从列表中删除。问题在于要检查WooCommerce中的订单是否存在,有一个元数据字段(如模型中所示)有不同的元数据项。其中一个是_shopify_order_id。所以我嵌套了一些任意的LINQ语句来尝试循环查找是否存在。我认为问题在于使用了动态类型,因为元数据的值的类型是不同的。所以当我运行它时,在元数据比较时会出现错误:

    Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Operator '==' cannot be applied to operands of type 'System.Text.Json.JsonElement' and 'string'
   at CallSite.Target(Closure, CallSite, Object, String)

我在想,比较字符串与动态类型可能存在问题吗?

解决方案

在两个方面都使用 ToString 进行比较可能会有些棘手。最好使用 string.Equals,它要求另一个项是字符串:

"_shopify_order_id".Equals(m.Key) && (m.Value.ToString() == order.Id.ToString())

对于订单ID比较,对于使用ToString也要谨慎 – 如果你有一个ID值为”123″的订单和一个值为123的键,即使它们的类型不同,比较结果也会为真。

所以你可能也会想要:

"_shopify_order_id".Equals(m.Key) && order.Id.Equals(m.Value)

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程