Обновление данных в рамках сервиса ADO.NET Data Services на основе LINQ to SQL

Мы с вами продолжаем исследовать возможности использования LINQ to SQL в качестве исходной модели данных для ADO.NET Data Services. Сегодня мы поговорим о возможности изменения данных.

Платформа ADO.NET Data Services предоставляет нам возможность не только выбирать данные через веб-сервис, но и обновлять их используя методы POST/PUT/MERGE/DELETE. В рамках самой модели данных необходимо реализовать интерфейс IQueryable (для каждой коллекции) для выборки данных, и IUpdatable (для всего класса-контекста) для обновления.

Вернемся к LINQ to SQL. Если мы попробуем создать модель данных LINQ to SQL, предоставить к ней доступ через ADO.NET Data Services и попробовать обновить данные, то мы с досадой обнаружим, что веб-сервис генерирует ошибку. При неглубоком изучении причины ошибки можно легко догадаться, что проблема заключается в том, что модель LINQ to SQL к сожалению не реализует IUpdateable. Здесь можно долго ругаться на разработчиков, но причины такого исхода очевидны: интерфейс IUpdatable – это составная часть ADO.NET Data Services. LINQ to SQL вышел намного раньше, чем ADO.NET Data Services. Отсюда можно сделать вывод, что реализовать еще не готовый интерфейс команда LINQ to SQL не могла.

Тем не менее, ограничение действительно серьезное и может существенно повлиять на конечное решение. Можно, конечно, отказаться от использования LINQ to SQL, но ведь это не наш метод :) Как справится с этой проблемой? Очень просто – реализовать IUpdatable вручную :)

Однако, взглянув на интерфес IUpdatable можно прийти в уныние, ведь там необходимо реализовать 12 методов с непрозрачной, на первый взгляд, логикой.

partial class NewsDataContext : IUpdatable
{
    public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
    {
        throw new System.NotImplementedException();
    }

    public void ClearChanges()
    {
        throw new System.NotImplementedException();
    }

    public object CreateResource(string containerName, string fullTypeName)
    {
        throw new System.NotImplementedException();
    }

    public void DeleteResource(object targetResource)
    {
        throw new System.NotImplementedException();
    }

    public object GetResource(System.Linq.IQueryable query, string fullTypeName)
    {
        throw new System.NotImplementedException();
    }

    public object GetValue(object targetResource, string propertyName)
    {
        throw new System.NotImplementedException();
    }

    public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
    {
        throw new System.NotImplementedException();
    }

    public object ResetResource(object resource)
    {
        throw new System.NotImplementedException();
    }

    public object ResolveResource(object resource)
    {
        throw new System.NotImplementedException();
    }

    public void SaveChanges()
    {
        throw new System.NotImplementedException();
    }

    public void SetReference(object targetResource, string propertyName, object propertyValue)
    {
        throw new System.NotImplementedException();
    }

    public void SetValue(object targetResource, string propertyName, object propertyValue)
    {
        throw new System.NotImplementedException();
    }
}

Я не буду вдаваться в смысл и детали реализации каждого метода. При первом же рассмотрении эти методы кажутся вполне логичными и понятными. Для того же, чтобы вы могли уже сейчас использовать возможность обновления данных через веб-сервис на базе модели данных LINQ to SQL предлагаю вам один из вариантов реализации данного интерфейса. Скачать его себе (и использовать в своих проектах) вы можете по ссылке ниже.

Как вы видите интерфейс реализуется в partial-классе. Это существенно, т.к. если вы его реализуете внутри автогенерируемого файла *.designer.cs, то вы подвержены потерять этот код при любом изменении данных.