Как я могу создать временные записи типов Linq-To-Sql, не вызывая проблем с дублированием ключа? - PullRequest
1 голос
/ 15 ноября 2011

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

        Crop_Variety v = new Crop_Variety();
        v.Type_ID = currentCropType.Type_ID;
        v.Variety_ID = r.Cells[0].Value.ToString();
        v.Description = r.Cells[1].Value.ToString();
        v.Crop = currentCrop;
        v.Crop_ID = currentCrop.Crop_ID;

К сожалению, в этом небольшом кусочке кода, потому что я говорю, что v.Crop = currentCrop, теперь currentCrop.Crop_Variety включает эту временную запись. И когда я иду, чтобы вставить записи этой сетки, которые являются новыми, у них есть ссылка на ту же запись Crop, и поэтому эти временные записи, которые уже существуют в базе данных, появляются дважды, вызывая ошибки дублирующихся ключей при отправке. *

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

Есть ли способ, которым я могу остановить Linq-To-Sql от автоматического добавления этих временных записей в свои коллекции таблиц?

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Я бы предложил пересмотреть код, который заполняет DataGridView (grid) записями.

И затем повторно посетите код, который работает с элементами из GridView, помня, что вы можете получить связанный элемент из строки сетки, используя следующий код:

public object GridSelectedItem
{
    get
    {
        try
        {
            if (_grid == null || _grid.SelectedCells.Count < 1) return null;
            DataGridViewCell cell = _grid.SelectedCells[0];
            DataGridViewRow row = _grid.Rows[cell.RowIndex];
            if (row.DataBoundItem == null) return null;
            return row.DataBoundItem;
        }
        catch { }
        return null; 
    }
}

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

Для этого типа приложения формы у меня обычно есть List _dataList внутри класса формы, затем основная сетка привязывается к этому списку через ObjectBindingList или другим способом.Таким образом, _dataList содержит все данные, которые должны быть сохранены при необходимости (пользователь нажал сохранить).

0 голосов
/ 22 февраля 2012

Когда вы назначаете ссылку на объект сущности, вы создаете связь между двумя объектами. Вот что вы делаете:

v.Crop = currentCrop;

Существует только один способ избежать этого: изменить сгенерированный код или сгенерировать / написать свой собственный. Я бы никогда этого не сделал.

Я думаю, вам будет лучше, если вы создадите собственный класс DTO вместо повторного использования сгенерированных сущностей. Я сделал оба подхода, и мне нравится последний намного лучше.

Редактировать: Вот пример кода, сгенерированного:

    [global::System.Data.Linq.Mapping.AssociationAttribute(Name="RssFeed_RssFeedItem", Storage="_RssFeed", ThisKey="RssFeedID", OtherKey="ID", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
    public RssFeed RssFeed
    {
        get
        {
            return this._RssFeed.Entity;
        }
        set
        {
            RssFeed previousValue = this._RssFeed.Entity;
            if (((previousValue != value) 
                        || (this._RssFeed.HasLoadedOrAssignedValue == false)))
            {
                this.SendPropertyChanging();
                if ((previousValue != null))
                {
                    this._RssFeed.Entity = null;
                    previousValue.RssFeedItems.Remove(this);
                }
                this._RssFeed.Entity = value;
                if ((value != null))
                {
                    value.RssFeedItems.Add(this);
                    this._RssFeedID = value.ID;
                }
                else
                {
                    this._RssFeedID = default(int);
                }
                this.SendPropertyChanged("RssFeed");
            }
        }
    }

Как видите, сгенерированный код устанавливает ссылку, говоря "value.RssFeedItems.Add (this);".

Если у вас много сущностей, для которых вам потребуется много DTO, вы можете сгенерировать классы DTO с помощью рефлексии.

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