2016-04-19 2 views
4

Я хотел бы создать приложение, которое считывает данные из базы данных, а затем показывает его через пользовательский интерфейс. Затем пользователь может добавлять/удалять/обновлять поля и сохранять их в БД, довольно стандартный, не так ли?DataBinding() не работает с Distinct() (Entity Framework)

У меня есть две таблицы: двигатели и меры. В таблице «Моторы» много полей, одна из которых - «компания». Конечно, может быть несколько моторов одной и той же компании, поэтому я бы хотел отфильтровать эти компании и получить только отдельные в comboBox.

Я все еще играю с языком и VS, поэтому я сделал простую версию пользовательского интерфейса, где пользователь может добавить новый двигатель, на самом деле пользователь может добавить поле компании, m пытается добавить новую компанию и посмотреть, будет ли она автоматически обновляться в comboBox.

Для этой цели я использую Entity Framework и этот учебник от 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 делает обновление и показывает каждую компанию (для каждого двигателя):

Нажмите кнопку Добавить -> «Список изменен!» всплывающее окно -> «Новый двигатель: идентификатор» Всплывающее

С фильтром:

Нажмите кнопку Добавить -> «Новый двигатель: идентификатор» Всплывающее

На самом деле двигатель добавляет, но он не показывает до перезапуска программы.

Любая идея будет высоко оценена. Надеюсь, я хорошо себя объяснил.

ответ

2

Следующая строка во втором примере разорвать связывание:

_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; 
+0

Благодарим вас за ответ DmitryG. Я думаю, что вы имеете в виду _context.Motors.Select (x => x.company) .Distinct(). Load(). Однако он не работает. Комбинированный код не заполняется данными. Если я пишу _context.Motors.Where (m => m.company == "UPV"). Load(); то я получаю comboBox с тремя «UPV» (потому что у меня есть 3 UPV-мотора). Если я добавлю новый с UPV как компанией, он добавит в список, так что у меня есть 4. Проблема в том, что если бы у меня была другая компания, она добавляет также, поэтому она не фильтрует компанию == «UPV» больше , Я думаю, что фильтр в предложении Load() применим только к первой загрузке, верно? – lyurealm

+0

>> Я думаю, что фильтр в предложении Load() применяется только в первой загрузке, верно? Да, ты прав. После некоторых изменений вы должны перезагрузить источник данных из контекста. – DmitryG

+0

Не могли бы вы подробно объяснить это? Вы имеете в виду, что я должен вызывать _context.Motors.Select (x => x.company) .Distinct(). Загрузить() из AddButton? – lyurealm

0

Эта линия

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(); 
+0

Прежде всего, спасибо за ваш ответ. Однако, похоже, он не работает даже с .ToList(). – lyurealm

Смежные вопросы