Устранит ли использование транзакции необходимость использования вторичных dataContexts для попытки вставки / обновления / удаления sql? - PullRequest
1 голос
/ 10 сентября 2009

Итак, у меня есть список заявок ИТ / разработчиков, хранящихся в базе данных через Linq-To-Sql. Попытки сохранения выполняются только по запросу пользователя или, если они говорят, сохранить при закрытии. Меня беспокоило то, что пользователь вносит изменения в 2 или более билетов без сохранения промежуточных.

По какой-то причине, если база данных отклоняет изменение на единицу, не дает мне много информации о том, с каким элементом или в каком поле и в каком билете возникла проблема, поэтому я могу связать его с предоставлением пользователю индикатора. Теперь я не могу сохранить хорошие данные в записях, которые они редактировали, потому что одно изменение застряло в очереди, и теперь SubmitChanges больше не работает.

Я построил систему буферизации, в которой каждый билет упакован в другой класс, чтобы изменения сохранялись в буфере, а не непосредственно в объекте linq to sql, где для каждого билета изменялось:

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

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

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

  • Будут ли транзакции правильно сбрасывать все изменения элемента или все элементы, которые SaveChanges попытается сохранить? впоследствии я ожидал, что hasChanges будет пустым, а SaveChanges ничего не сделает.
  • Есть ли лучший способ отправить отдельные изменения строки одновременно в linq-to-sql?
  • Я что-то упускаю в исключениях SaveChanges, которые действительно помогли бы мне узнать, в какой строке и в каком поле этой строки возникла проблема?

Возможно, я не должен позволять (из-за linq-to-sql или из-за того, что в реальном мире не требуется возможность вносить изменения в несколько устройств без принятия решения о сохранении или нет) пользователю оставлять билет до тех пор, пока он не примет решение хотят ли они сохранить изменения или нет?

1 Ответ

0 голосов
/ 15 сентября 2009

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

Это родительский класс для моих бизнес-объектов, которые обертываются вокруг сущности linq.

public class BufferedLinqChange
{
    LqGpsDataContext _dataContext;

    internal BufferedLinqChange(LqGpsDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    protected void SetBufferedProperty<T>(string key,Action linqAction
        ,bool linqEqualsValue,Action bufferAction)
    {
        if (linqEqualsValue)
        {
            if (Changes.ContainsKey(key))
                Changes.Remove(key);
        }
        else
        Changes.InsertOrUpdate(key, linqAction); bufferAction();
    }

    protected Dictionary<String, Action> Changes = new Dictionary<string, Action>();

    public int ChangeCount { get { return Changes != null ? Changes.Count : 0; } }
    public bool hasChanges { get { return Changes != null ? Changes.Count > 0 : false; } }

    public void SubmitChanges()
    {
        _dataContext.SubmitChanges();
        if (ChangeCount > 0)
        {
            Changes.ForEach((item) => item.Value.Invoke());
            _dataContext.SubmitChanges();
        }
    }
    public void CancelChanges()
    {
        if (Changes != null)
            Changes.Clear();
    }
}

Вот пример одного из свойств:

#region assetTag


    String _AssetTag;
    public const String STR_assetTag = "assetTag";
    public String assetTag
    {
        get { return (Changes.ContainsKey(STR_assetTag) ? _AssetTag : Asset.assetTag); }
        set
        {
            SetBufferedProperty<String>(STR_assetTag
                , () => Asset.assetTag = value, Asset.assetTag == value, () => _AssetTag = value);
        }
    }
    #endregion
...