使用System.Linq.Dynamic.Core查询具有成员字典的对象列表时无法获得多个结果

时间:2018-10-02 01:47:04

标签: c# .net linq dynamic core

我正在使用System.Linq.Dynamic.Core v1.0.8.18

我是我所拥有的对象的缩写-我消除了用于序列化/反序列化的JSON标签以及构造函数。以下是订单中订单项的缩写类。请注意,此对象是从JSON反序列化的,“其他”字典的目的是捕获对象中未明确定义的任何名称/值对(在测试和生产中应完全一样):

public partial class OrderRequestItem
{

    public string line_number { get; set; }
    public decimal quantity { get; set; }
    public string supplier_id { get; set; }
    public string supplier_aux_id { get; set; }
    public decimal unitprice { get; set; }
    public string description { get; set; }
    public string uom { get; set; }
    public IDictionary<string, object> other;

    public decimal extension
    {
        get
        {
            return unitprice * quantity;
        }
    }

    public bool validated { get; set; }
    public bool rejected { get; set; }
}

我正在尝试根据JSON配置文件条目使用以下代码“拆分”订单,该配置文件指定了要拆分订单的字段(参数2):

   private List<OrderRequest> SplitOrder(OrderRequest originalOrder, string[] orderSplitLineItemFields = null)
    {
        var retval = new List<OrderRequest>();
        if (null == orderSplitLineItemFields || originalOrder.items.Count < 2) //Can't return more than one order if we don't have fields to split by, and we don't have at least 2 line items.
        {
            retval.Add(originalOrder);
        }
        else
        {
            var bareOrderHeader = (OrderRequest)originalOrder.DeepClone();
            bareOrderHeader.items.Clear();
            var firstLineItem = originalOrder.items[0];
            var validOrderSplitLineItemFields = new List<string>();
            var dynamicQueryBase =  new List<string>();
            int validFieldCount = 0;
            foreach (var field in orderSplitLineItemFields)
            {
                if (firstLineItem.HasProperty(field))
                {
                    validOrderSplitLineItemFields.Add(field);
                    dynamicQueryBase.Add(field + " = @" + validFieldCount++);
                }
                else if (null != firstLineItem.other[field])
                {
                    validOrderSplitLineItemFields.Add("other[\"" + field + "\"]");
                    dynamicQueryBase.Add("other[\"" + field + "\"]" + " = @" + validFieldCount++);
                }
            }
            if(validOrderSplitLineItemFields.Count<1) //Can't return more than one order if we don't have valid fields to split by.
            {
                retval.Add(originalOrder);
            }
            else //We have valid fields to split the order, so we might be able to return more than one order.
            {

                string distinctFields = String.Join(",", validOrderSplitLineItemFields);
                var distinctFieldValues = originalOrder.items.AsQueryable().Select(distinctFields).Distinct();
                var dynamicWhere = string.Join(" and ", dynamicQueryBase);
                var originalLineItems = originalOrder.items.AsQueryable();
                foreach (var distinctResult in distinctFieldValues)
                {
                    var newOrderSplit = (OrderRequest)bareOrderHeader.DeepClone();

                    var results = originalLineItems.Where(dynamicWhere, distinctResult);
                    foreach (var lineitem in results)
                    {
                        newOrderSplit.items.Add(lineitem);
                    }

                    retval.Add(newOrderSplit);
                }
            }
        }
        return retval;
    }

我尝试拆分的字段称为“ requested_delivery_date”,该字段已正确传递给SplitOrder函数。由于这不是OrderRequestItem的实际属性,因此拆分代码检查(实际上成功完成了)查看/查找“ other”属性中的字典条目,并将该字段适当地添加到要查询的动态字段列表中, -(我这样做是因为“需要”专门定义的属性,而我无法预测将来在与其他买方的订单上可能还会发送的其他字段。)

我有一个示例订单文件,其中包含4个订单项。第1、2、3行都具有定义的other [“ requested_delivery_date”] = 2018-09-29,第4行具有other [“ requested_delivery_date”] = 2018-09-30。

根据代码,我希望返回两个订单,一个订单项1-3,而另一个订单项仅第4行。但是,我实际上得到的是两个订单,一个仅包含订单项#1,另一个仅包含订单项#4。好像这条线

var results = originalLineItems.Where(dynamicWhere, distinctResult);

当我查询作为OrderRequestItem成员的字典时,只会返回一个结果。

在一天中的大部分时间里,我一直在墙上碰头,我不明白为什么当调试器向我显示我要查询的原始项目列表有更多结果时,我只能得到一个结果火柴。我开始认为这是当前版本的System.Linq.Dynamic.Core中的错误。

任何帮助/建议表示赞赏!请记住,我需要使用动态linq,因为我将一直在处理订单项上的新字段或更改过的其他字段-因此,这里不选择返回“常规linq”。

2 个答案:

答案 0 :(得分:2)

更改了此

dynamicQueryBase.Add("other[\"" + field + "\"]" + " = @" + validFieldCount++);

对此

dynamicQueryBase.Add("other[\"" + field + "\"].ToString()" + " = @" + validFieldCount++);

使它按预期工作。

答案 1 :(得分:0)

我现在无法测试,也许“ where”的默认返回值只是一个项目。
试试

var results = originalLineItems.Where(dynamicWhere, distinctResult).ToList();

然后检查它是否工作正常。