2011-04-12 54 views
3

我想使用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类,以便它可以表示查询时存在的数据库表的形状。

例如,假设数据库包含一个称为人口的表,我想能够支持以下的OData查询:

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

其中代码是char(2)含有与美国状态柱码。

到目前为止,使用的任何企图任一种ExpandoObject(代替表类),或具有表类从DynamicObject派生未能创造一个可行OData源,导致下面“请求错误”:

异常消息是'内部服务器错误。不支持'ServiceLibrary.Table'类型。'

与表示异常的堆栈跟踪内部

System.Data.Services.Providers.ReflectionServiceProvider.BuildHierarchyForEntityType 

被抛出有一种方法来创建暴露属性(表示相应的数据库表的列)的表类动态可用于由WCF数据服务来浏览一个SQL数据库?

+0

你所要求的是可能的,但它是搞砸了。首先,你不应该通过Web服务传递数据库对象 - 客户端不需要知道数据库的实现。对于两种情况,您绝对不应该常规更改数据库模式,尤其是不要每天多次更改数据库模式。 – 2011-04-13 00:28:57

+0

不过,我只是用这个例子来说明问题。实际上,客户端实际上并不知道(或关心)对象的存储方式,而架构实际上并没有经常改变这种情况,但我想指出重新编译不是一个实际的选择。 – 2011-04-13 03:56:31

+0

所以,现在你嘲笑我:我将如何去解决这个问题?我不怀疑它是因为我无法使用传统方法解决它而搞砸了。 – 2011-04-13 03:57:46

回答

3

OData Provider Toolkit包含R/W非类型化数据提供程序的示例实现,它可以很容易地修改为返回元数据和表数据。