Что является хорошим способом разрешить двустороннюю привязку к IQueryable с DataGridView? - PullRequest
2 голосов
/ 17 июня 2011

Я пытался найти решение этой проблемы, но не смог найти ничего, что помогло бы.

Я пытаюсь связать результаты LINQ-to-SQLзапрос к DataGridView таким образом, чтобы я мог добавлять новые строки и редактировать существующие строки, которые затем соответствующим образом обновят базу данных.Простое выполнение следующего создает таблицу только для чтения:

myDataGridView.DataSource = from item in myDatabase.Parts
                 select new
                 {
                    item.Name,
                    item.Description
                 };

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

Что я думаю сделатьсоздает класс клиента, который представляет анонимный тип, возвращаемый выбором, преобразует запрос в список с помощью метода ToList(), затем оборачивает его в класс, который будет обрабатывать соответствующие события DataGridView при помещении в VirtualMode, обрабатывая соответствующие запросы к базе данных по мере необходимости.

Я просто надеюсь, что есть лучший вариант.

Ответы [ 2 ]

1 голос
/ 17 июня 2011

Как вы уже видели, когда вы создаете новый, вы создаете анонимный тип и теряете возможность иметь двухстороннюю привязку к данным, поскольку она неизменна.

Согласно этой статье MSDN вы можете получить двухстороннюю привязку данных из коробки с Linq-to-SQL, когда linq может "найти базовую таблицу". Я не уверен, исключает ли это базовые объединения но я подозреваю, что это так.

В этом вопросе Linq to SQL и параллелизм с шаблоном хранилища Rob Conery Я обсуждаю шаблон, представленный Робом Конери, который я использовал, который давал двухстороннюю привязку к объектам и допускал объединения и тому подобное, но представлял объект домена, который находился на объекте DataContext - хотя, как я отмечаю в этом вопросе, выполнение этого способа убивает отслеживание параллелизма, и вам необходим код отображения, чтобы получить от объектов домена обратно к объектам DataContext.

Это звучит похоже на то, о чем вы заботитесь, и, по крайней мере, избавляет вас от необходимости расширять виртуальный режим.

У меня не было возможности много работать с Entity Framework 4, но, возможно, история лучше для этой ситуации. Когда я рассматривал это в Linq-to-SQL год или два назад, я никогда не находил отличного решения (что, конечно, не означает, что его нет!)

0 голосов
/ 17 июня 2011

Потратив немного больше времени на проблему, я стал больше изучать классы BindingList и BindingSource.Довольно хорошим решением моей проблемы было сделать что-то похожее на то, что я предлагал в своем вопросе, но с использованием пользовательского объекта BindingList.

public class PartListBindingList : BindingList<PartListBindingItem>
{
    private readonly MyDatabase _Database;
    private bool _IsInitialized = false;

    public PartListBindingSource(MyDatabase database)
    {
        _Database = database;

        foreach (var part in _Database.Parts)
        {
            var item = new PartListBindingItem()
            {
                PartID = part.PartID
                Name = part.Name,
                Description = part.Description
            };

            Add(item);
            BindItem(item);
        }

        _IsInitialized = true;
    }

    protected override void OnListChanged(ListChangedEventArgs e)
    {
        base.OnListChanged(e);

        if (!_IsInitialized) return;

        switch (e.ListChangedType)
        {
            case ListChangedType.ItemAdded:
                // Add new item to database
                break;

            case ListChangedType.ItemDeleted:
                // Add new item to database
                break;
        }
    }

    private void BindItem(PartListBindingItem item)
    {
        item.Changed += (s, e) =>
        {
            // Update the entry in the database.
        };
    }
}

public class PartListBindingItem
{
    public event EventHandler Changed;

    private int _PartID;
    private string _Name;
    private string _Description;

    public int PartID
    {
        get { return _PartID; }
        set
        {
            _PartID= value;
            OnChanged();
        }
    }

    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value;
            OnChanged();
        }
    }

    public string Description
    {
        get { return _Description; }
        set
        {
            _Description= value;
            OnChanged();
        }
    }

    private OnChanged()
    {
        var changed = Changed;
        if (changed != null)
        {
            changed(this, EventArgs.Empty);
        }
    }
}

Этот скелетный дизайн может быть адаптирован для работы с более сложнымипривязки базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...