LINQ to SQL - Отслеживание новых / грязных объектов - PullRequest
8 голосов
/ 12 мая 2009

Есть ли способ определить, не был ли объект LINQ еще не вставлен в базу данных (новый) или был изменен с момента последнего обновления (грязный)? Я планирую привязать свой пользовательский интерфейс к объектам LINQ (используя WPF), и мне нужно, чтобы он вел себя по-разному в зависимости от того, находится ли объект уже в базе данных.

MyDataContext context = new MyDataContext();
MyObject obj;
if (new Random().NextDouble() > .5)
    obj = new MyObject();
else
    obj = context.MyObjects.First();
// How can I distinguish these two cases?

Единственное простое решение, которое я могу придумать, состоит в том, чтобы установить первичный ключ новых записей в отрицательное значение (мои PK являются полем идентификации и, следовательно, будут установлены в положительное целое число на INSERT ). Это будет работать только для обнаружения новых записей. Это также требует идентификаторов PK и контроля кода, создающего новый объект.

Есть ли лучший способ сделать это? Похоже, что LINQ должен внутренне отслеживать состояние этих объектов, чтобы он мог знать, что делать на context.SubmitChanges(). Есть ли способ получить доступ к этому «состоянию объекта»?

Разъяснение Видимо, мой первоначальный вопрос сбивал с толку. Я не ищу способ вставки или обновления записей. Я ищу способ, учитывая любой объект LINQ, чтобы определить, был ли этот объект не был вставлен (новый) или был изменен с момента его последнего обновления (грязный).

Ответы [ 5 ]

14 голосов
/ 13 мая 2009

ChangeSet changes = context.GetChangeSet ();

Если changes.Inserts.Contains (yourObject), то он новый и будет вставлен при вызове SubmitChanges

Если changes.Updates.Contains (yourObject), он уже находится в базе данных и будет обновлен в SubmitChanges ()

2 голосов
/ 28 мая 2009

Я создаю частичный класс для каждого объекта, который создает LINQ (Объекты данных), и каждый объект реализует интерфейс IDataObject

/// <summary>
/// This interface is used to implement IsNew in all LINQ objects so a Generic Save method 
/// can be used.
/// </summary>
public interface IDataObject
{

    #region Properties


        #region IsNew
        /// <summary>
        /// Is this a new object
        /// </summary>
        bool IsNew
        {
            get;
        } 
        #endregion


    #endregion

} 
#endregion

В каждом объекте данных я реализую Свойство IsNew, чтобы возвращать true, если PrimaryKey был установлен:

/// <summary>
/// Is this a new object
/// </summary>
public bool IsNew
{
    get
    {
        // initial value
        bool isNew = (this.CustomerID > 0);

        // return value
        return isNew;
    }
}

Затем в моем DataContext я приводил объект, который нужно сохранить как IDataObject, и, если он новый, я вызываю InsertOnSubmit () перед вызовом SubmitChanges ().

Возможно, это не самый простой способ, но он позволяет сохранить все объекты в общем виде.

Каждой таблице требуется несколько минут для реализации интерфейса, но он позволяет вызывать общий метод Save ().

1 голос
/ 12 мая 2009

Объект DataContext внутренне отслеживает изменения данных, чтобы он мог оптимизировать запросы SQL, генерируемые при вызове SubmitChanges ().

Если вы хотите вставить новые объекты в базу данных, а не обновить существующие объекты, вы должны сделать что-то вроде:

MyDataContext context = new MyDataContext();
MyObject obj;
if (new Random().NextDouble() > .5)
{
    obj = new MyObject();
    context.MyObjects.InsertAllOnSubmit(obj);
}
else
    obj = context.MyObjects.First();

Теперь, когда вы вызываете SubmitChanges (), он генерирует как INSERT, так и UPDATE, если это необходимо. В зависимости от того, насколько быстро вам нужен первичный ключ для вашего нового объекта, вы можете сразу же отправить его, чтобы отправить объект, очистить отслеживание изменений и получить новый первичный ключ.

0 голосов
/ 23 июня 2012

Вопрос Как добавить свойство «IsDirty» в сущность LINQ to SQL? имеет ответ из ongle , как реализовать свойство IsDirty используя событие PropertyChanged.

Ограничение: показывает IsDirty как true, если свойство было изменено, но затем отменено.

0 голосов
/ 20 апреля 2010

Есть интерфейсы INotifyPropertyChanging и INotifyPropertyChanged, у которых есть определенные методы, которые должны запускаться при вставке, что позволяет вам знать, если объект испачкается. Если вы используете SQLMetal, он делает это автоматически. если вы пишете свои собственные классы сущностей, вы сами пишете этот сантехнический персонал. Но я не уверен, подходит ли это решение с точки зрения масштабируемости. Я не проверял это. Кажется, что у него могут быть проблемы, поскольку он запускает событие на машине, которая выполняет вставку.

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