DataBinding()无法与Distinct()(实体框架)一起使用

本文关键字:框架 一起 实体 DataBinding Distinct | 更新日期: 2024-10-18 22:00:36

我想创建一个从数据库中读取数据,然后通过UI显示数据的应用程序。然后用户可以添加/删除/更新字段并将其保存到DB中,这是非常标准的,对吧?

我有两张桌子:马达和度量。电机表有很多字段,其中一个字段是"公司"。当然,同一家公司可能有几台电机,所以我想过滤这些公司,在comboBox中只获得不同的电机。

我仍然在玩语言和VS,所以我制作了一个简单版本的UI,用户可以在其中添加新的马达,事实上,用户可以添加公司字段,因为我正在尝试添加一个新的公司,看看它是否会在comboBox中自动更新。

为此,我使用实体框架和msdn的本教程进行数据绑定:

https://msdn.microsoft.com/en-us/data/jj682076.aspx

问题是,当我添加一个新的电机(与一家新公司)时,如果我过滤不同的电机,它就不会更新,我的意思是,以下代码确实有效,并自动更新所有公司的comboBox:

        private void MainForm_Load(object sender, EventArgs e)
    {
        _context = new MotorsContext();
        _context.Motors.Load();
        this.companyBindingSource.DataSource = _context.companies.ToBindingList();
        companyBindingSource.ListChanged += CompanyBindingSource_ListChanged;
    }

而以下则不然

private void MainForm_Load(object sender, EventArgs e)
{
    _context = new MotorsContext();
    _context.Motors.Load();
    this.companyBindingSource.DataSource = _context.Motors.Local.ToBindingList().Select(x => x.company).Distinct();
    companyBindingSource.ListChanged += CompanyBindingSource_ListChanged;
}

我创建了一个ListChanged方法来查看软件何时检测到列表确实发生了更改。在第一个代码中,它确实会触发,但在第二个代码中没有。也许当我添加过滤器时,观察者没有检测到列表中的变化?

private void CompanyBindingSource_ListChanged(object sender, ListChangedEventArgs e)
{
    MessageBox.Show("List changed!");
}

最后,添加电机按钮:

private void button1_Click_1(object sender, EventArgs e)
{
    if (!string.IsNullOrWhiteSpace(textBox1.Text))
    {
        Motor m = new Motor();
        m.company = textBox1.Text;
        _context.Motors.Add(m);
        _context.SaveChanges();
        MessageBox.Show($"New motor, id: {m.motorID}");
    }
}

在第一个实现中,comboBox会更新并显示每个公司(对于每个电机):

按下添加按钮->"列表已更改!"弹出->"新电机:id"弹出

带过滤器:

按下添加按钮->"New motor:id"弹出

事实上,电机会添加,但直到程序重新启动时才会显示。

任何想法都将不胜感激。我希望我已经很好地解释了自己。

DataBinding()无法与Distinct()(实体框架)一起使用

第二个例子中的以下行破坏了绑定:

_context.Motors.Local.ToBindingList().Select(x => x.company).Distinct();

原因是.Select(x => x.company).Distinct()的结果不是BindingList<Motor>,而是简单的IEnumerable<string>

使用以下替代品:

var _companies = _context.Motors.Select(x => x.company).Distinct().ToList();
this.companyBindingSource.DataSource = _companies;

此行

this.companyBindingSource.DataSource = _context.Motors.Local.ToBindingList().Select(x => x.company).Distinct();

返回IEnumerable<T>。在您的情况下,您希望它成为列表,所以添加.ToList();

this.companyBindingSource.DataSource = _context.Motors.Local.ToBindingList().Select(x => x.company).Distinct().ToList();