Динамическая модель сущности для службы данных WCF

Я хочу предоставить содержимое базы данных SQL в виде канала OData с помощью службы данных WCF.

Все работает хорошо, пока схема базы данных SQL не меняется. После добавления таблицы базы данных или изменения модель сущности устаревает. Перекомпилировать службу данных нельзя, поскольку схема может меняться несколько раз в день.

Я определяю службу данных таблицы:

public class TablesDataService
{
    private static List<Table> _tables;

    static TablesDataService()
    {
        _tables = new List<Table>();
        // query the database and add a table entity model for each table
    }

    public IQueryable<Table> Tables
    {
        get { return _tables.AsQueryable<Table>(); }
    }
}

который использует следующий POCO для представления отдельной таблицы:

[DataServiceKey("Name")]
public class Table
{
    public Table(string name)
    {
        Name = name;
    }

    public string Name { get; private set; }
}

Служба данных WCF использует следующий класс в WcfDataService.svc:

public class WcfDataService : DataService<TablesDataService>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        config.SetEntitySetAccessRule("Tables", EntitySetRights.All);
    }
}

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

Например, если предположить, что база данных содержит таблицу Population, я хотел бы иметь возможность поддерживать следующий запрос OData:

http://localhost/WcfDataService.svc/Tables('Population')?$filter=Code eq 'CA'

где Code — столбец char(2), содержащий коды штатов США.

До сих пор любые попытки использовать либо ExpandoObject (вместо класса Table), либо класс Table, производный от DynamicObject, не привели к созданию работоспособного канала OData, что привело к следующей «Ошибке запроса»:

Сообщение об исключении: «Внутренняя ошибка сервера. Тип ServiceLibrary.Table не поддерживается.

с трассировкой стека, показывающей исключение, выбрасываемое внутри

System.Data.Services.Providers.ReflectionServiceProvider.BuildHierarchyForEntityType

Есть ли способ создать класс таблицы, который динамически предоставляет свойства (представляющие столбцы соответствующей таблицы базы данных), которые могут использоваться службой данных WCF для просмотра базы данных SQL?


person Philipp Schmid    schedule 12.04.2011    source источник
comment
То, о чем вы просите, возможно, но это испорчено. Во-первых, вы не должны передавать объекты базы данных через веб-сервисы — клиенту не нужно знать о реализации базы данных. Во-вторых, вам определенно не следует регулярно менять схему базы данных, особенно несколько раз в день.   -  person Greg Sansom    schedule 13.04.2011
comment
Все хорошо, однако я просто использовал этот пример, чтобы проиллюстрировать проблему. На самом деле клиент на самом деле не знает (или не заботится), как хранятся объекты, и схема на самом деле не меняется так часто, но я хотел подчеркнуть, что перекомпиляция не является практичным вариантом.   -  person Philipp Schmid    schedule 13.04.2011
comment
Итак, теперь, когда вы дразнили меня: как мне решить эту проблему? Я не сомневаюсь, что он запутан, поскольку я не смог решить его традиционными методами.   -  person Philipp Schmid    schedule 13.04.2011
comment
Может быть, недавно выпущенная CTP-служба WCF Data Services, которая допускает наследование, могла бы решить эту проблему?   -  person Philipp Schmid    schedule 13.04.2011


Ответы (1)


Набор OData Provider Toolkit содержит пример реализации R/ W Поставщик нетипизированных данных, который можно легко изменить для возврата метаданных и табличных данных.

person Philipp Schmid    schedule 25.04.2011