更新KeyValue对的列表

时间:2017-03-29 17:30:11

标签: c# linq

我有一个WPF应用程序,我需要实现这个概念:

comboboxdatagridcombobox包含卖家列表,数据网格包含他们销售的商品的费率。

我想要这样的事情:

client -> null

item    |   rate
--------------------
itemA   |   0.00
itemB   |   0.00
itemC   |   0.00

如果未选择client(卖家),则items的所有费率均默认为0.00。

现在,我们假设我选择client名称为clientA,但不会卖ItemB。然后,显示应反映这一点。

client -> clientA

item    |   rate
--------------------
itemA   |   5.00
itemB   |   0.00
itemC   |   8.00

基本上,对于nullitems client不出售,它应该显示0.00而不是Dictionary

这实际上是WPF的工作,如果是ObservableDictionary,则为Caliburn

但是,我正在使用BindableCollection,我想使用if (SelectedReferenceClient == null) { Rates = new BindableCollection<KeyValuePair<string, decimal>>(itemrepository.FindWhere(c => true).Select(c => new KeyValuePair<string, decimal>(key: c.Name, value: 0)));; } //retrieve all items and put value to zero. var SelectedClientRates = new List<KeyValuePair<string, decimal>>(raterepository.FindWhere(c => c.Client == SelectedClient).Select(c => new KeyValuePair<string, decimal>(key: c.ItemName, value: c.Rate))); //get rates of items they sell foreach (var a in SelectedClientRates) { var b = Rates.FirstOrDefault(c => c.key == a.key); b.value = a.value; }//update the values in BindingCollection 来解决它。

所以,我有类似的东西:

LINQ

这可能有用,但它很吵,而且它很笨拙。是否有任何LINQ方法可以做到这一点?由于BindableCollection憎恶副作用,我首先想到的是它是不可能的。

但是,如果我想坚持ObservableDictionary而不使用{{1}},还有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

如果创建新的BindableCollection<T>实例是一个选项(而不是更新现有实例),则可以使用LINQ构建IEnumerable<T>查询并将其传递给BindableCollection<T>构造函数重载接受{{ 1}}:

IEnumerable<T>

LINQ部分是2个枚举之间的简单left outer join。左可枚举包含所有项目,并从存储库或已填充的存储中获取,而右可枚举包含所选项目/值对,并从其存储库中获取相应的过滤器。

一旦var keys = SelectedReferenceClient == null ? itemrepository.FindWhere(c => true).Select(c => c.Name) : Rates.Select(rate => rate.Key); var rates = raterepository.FindWhere(c => c.Client == SelectedClient).Select(c => new KeyValuePair<string, decimal>(key: c.ItemName, value: c.Rate)); var combined = from key in keys join rate in rates on key equals rate.Key into match from rate in match.DefaultIfEmpty() select new KeyValuePair<string, decimal>(key: key, value: rate.Key != null ? rate.Value : 0); Rates = new BindableCollection<KeyValuePair<string, decimal>>(combined); 运算符完成相关,结果值将根据匹配的存在/不存在来确定 - 匹配值或0.这里唯一不寻常的是匹配存在的检查 - 通常我们使用left outer join之类的东西,但是因为right != nullright(值类型),我们使用结构的字符串成员来达到同样的目的。

答案 1 :(得分:0)

参见下面的示例代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication49
{
    class Program
    {

        static void Main(string[] args)
        {
            string SelectedClient = "";
            List<RateRepository> raterepository = new List<RateRepository>();
            Dictionary<string, decimal> SelectedClientRates = raterepository.Where(c => c.Client == SelectedClient)
                .GroupBy(x => x.ItemName, y => y.Rate)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

        }
    }
    public class RateRepository
    {
        public string Client { get; set; }
        public string ItemName { get; set; }
        public decimal Rate { get; set; }
    }

}