Обновление BindingSource после вставки (Linq To SQL)

У меня есть сетка, привязанная к таблице BindingSource, которая привязана к таблице DataContext, например:

myBindingSource.DataSource = myDataContext.MyTable;
myGrid.DataSource = myBindingSource;

Я не мог обновить BindingSource после вставки. Это не сработало:

myDataContext.Refresh(RefreshMode.OverwriteCurrentValues, myBindingSource);
myBindingSource.ResetBinding(false);

Ни это:

myDataContext.Refresh(RefreshMode.OverwriteCurrentValues, myDataContext.MyTable);
myBindingSource.ResetBinding(false);

Что я должен делать?


person dstr    schedule 20.10.2009    source источник


Ответы (7)


Я решил проблему, но не так, как хотел.

Оказывается, DataContext и Linq To SQL лучше всего подходят для выполнения единичных операций. Означает, что вы создаете DataContext, выполняете свою работу, отбрасываете его. Если вам нужна другая операция, создайте другую.

Единственное, что мне нужно было сделать для этой проблемы, это воссоздать мой DataContext, например this.dx = new MyDataContext();. Если вы этого не сделаете, вы всегда получите устаревшие/кешированные данные. Из того, что я читал в различных сообщениях в блогах/форумах, DataContext легковесен и делает это A-OK. Это был единственный способ, который я нашел после поиска в течение дня.

person dstr    schedule 23.10.2009

И напоследок еще одно рабочее решение.

Это решение отлично работает и не требует повторного создания DataContext.

  1. Вам необходимо сбросить внутренний кеш таблицы. для этого вам нужно изменить частное свойство cachedList таблицы с помощью отражения.

Вы можете использовать следующий код утилиты:

    public static class LinqDataTableExtension
    {
        public static void ResetTableCache(this ITable table)
        {
            table.InternalSetNonPublicFieldValue("cachedList", null);
        }

        public static void ResetTableCache(this IListSource source)
        {
            source.InternalSetNonPublicFieldValue("cachedList", null);
        }

        public static void InternalSetNonPublicFieldValue(this object entity, string propertyName, object value)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");
            if(string.IsNullOrEmpty(propertyName))
                throw new ArgumentNullException("propertyName");

            var type = entity.GetType();
            var prop = type.GetField(propertyName, BindingFlags.NonPublic | BindingFlags.Instance);
            if (prop != null)
                prop.SetValue(entity, value);
// add any exception code here if property was not found :)
        }
    }

используя что-то вроде:

   var dSource = Db.GetTable(...)
   dSource.ResetTableCache();
  1. Вам необходимо сбросить BindingSource, используя что-то вроде:

    _BindingSource.DataSource = новый список(); _BindingSource.DataSource = dSource; // hack - обновить список привязок

  2. Наслаждайтесь :)

person IgorS    schedule 08.04.2010

Источник данных сетки Referesh по новому запросу вместо Contest.Table. Простое решение ‹ Но работает.

Где, например. !!!!! Спасибо - проблема решена через несколько дней !!! но таким простым способом..

CrmDemoContext.CrmDemoDataContext Context = new CrmDemoContext.CrmDemoDataContext();

var query = from it in Context.Companies select it;
// initial connection
dataGridView1.DataSource = query;

после изменения или добавления данных

Context.SubmitChanges();
//call here again 
dataGridView1.DataSource = query;
person Anil    schedule 23.09.2011

У меня та же проблема. Я использовал форму для создания строк в своей таблице без сохранения контекста каждый раз. К счастью, у меня было несколько форм, которые делали это, и одна корректно обновляла сетку, а другая нет.

Единственная разница?
Я привязал один объект к объекту так же (без использования bindingSource), как и вы:

myGrid.DataSource = myDataContext.MyTable;

Второй я связал:

myGrid.DataSource = myDataContext.MyTable.ToList();

Второй способ сработал.

person Sean    schedule 17.02.2011

Я думаю, вам также следует обновить/обновить datagrid. Вам нужно принудительно перерисовать сетку.

person Sharique    schedule 20.10.2009

Не уверен, как вы вставляете строки. У меня была такая же проблема при использовании DataContext.InsertOnSubmit(row), но когда я просто вставлял строки в BindingSource вместо BindingSource.Insert(Bindingsource.Count, row) и использовал DataContext только для DataContext.SubmitChanges() и DataContext.GetChangeSet(). BindingSource вставляет строки как в сетку, так и в контекст.

person Atomosk    schedule 03.11.2011

ответ от Атомоск помог мне решить аналогичную проблему - большое спасибо Атомоск!

Я обновил свою базу данных с помощью следующих двух строк кода, но DataGridView не показал изменений (он не добавил новую строку):

this.dataContext.MyTable.InsertOnSubmit(newDataset);
this.dataContext.SubmitChanges();

Где для this.dataContext.MyTable было задано свойство DataSource объекта BindingSource, которое было задано для DataSource свойство объекта DataGridView. В коде это выглядит так:

DataGridView dgv = new DataGridView();
BindingSource bs = new BindingSource();
bs.DataSource = this.dataContext.MyTable; // Table<T> object type
dgv.DataSource = bs;

Установка bs.DataSource равной null и после этого возврат к this.dataContext.MyTable также не помогла обновить DataGridView.

Единственным способом обновить DataGridView новой записью был совершенно другой подход, добавив его в BindingSource вместо соответствующей таблицы DataContext, как упоминалось в Atomosk.

this.bs.Add(newDataset);
this.dataContext.SubmitChanges();

Без этого bs.Count; вернул меньшее число, чем this.dataContext.MyTable.Count(); Это не имеет смысла и, по моему мнению, является ошибкой в ​​​​модели привязки.

person Clemens    schedule 18.04.2013