如何对动态和字符串进行比较运算符

How to do a comparison operator on dynamic and string

提问人:Irish Redneck 提问时间:10/21/2023 更新时间:10/21/2023 访问量:56

问:

我有两个绑定到以下模型的 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)

我认为将字符串与动态进行比较存在问题?

C# LINQ ASP.NET 核心 模型绑定

评论

0赞 D Stanley 10/21/2023
为什么 ?您是否能取回字符串以外的值?在这种情况下,您期望比较结果如何?Keydynamic
0赞 D Stanley 10/21/2023
为了帮助理解,它不是一个“类型”——它基本上告诉编译器“我不知道类型是什么,所以将任何绑定推迟到运行时。如果 的值在运行时是字符串,则比较将正常工作。dynamicKey
0赞 Irish Redneck 10/21/2023
发现问题。我想m.Key需要是m.Key.ToString() 。我让它动态化,因为它有时会跳闸一个错误,它有时无法将字符串转换为 int。所以我猜有时数据并不总是一个字符串。那么动态不是最好的做法,还是我可以在绑定时强制每个东西都使用字符串?
0赞 D Stanley 10/21/2023
如果可以是字符串或 int,则没问题。不过,我建议在比较中添加类型检查(Keydynamicm.Key is string && m.Key == "_shopify_order_id")
0赞 D Stanley 10/21/2023
如果您希望 和 的键值不同,我不会在绑定时强制使用字符串。在这种情况下,你没有这样做,但我没有;不知道可能还有什么其他值,以及是否应该区别对待这些值。123"123"Key

答:

0赞 D Stanley 10/21/2023 #1

在两边进行比较可能很棘手。最好使用要求其他项目为字符串的:ToStringstring.Equals

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

我还要谨慎使用订单 ID 比较 - 如果您的订单的 ID 值为“123”,键值为“123”,即使它们属于不同的类型,比较也是正确的。ToString123

因此,您可能还需要:

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