从实体框架中的表值函数创建集合

Big*_*oss 5 c# entity-framework wcf-data-services entity-framework-5

我有一个包含非常大的表的数据库(其中一些可能有超过1,000,000条记录),并且该数据库的每个用户都应该看到一些这样的数据,因此我们有多个获得用户ID的TVF(表值函数)并选择那些该用户可见的表的记录(此操作需要多个SELECT语句,我认为调用TVF远比在代码中实现它好得多).在我的客户程序的第一个版本中,我有一个类IQueryable,它具有使用LinqToSql实现的多个类型的属性,并且它工作得很好.现在我有一个客户端想要使用我的程序集来编写WCF数据服务,所以我必须编写一个派生自DbContext(使用EF)的类,可以在指定的服务中使用.我的问题是:

  • DbContext自动公开DbSet其中定义的所有属性,因此每个具有最低访问级别的用户都可以看到表的整个数据(当然客户端应用程序将限制数据,但客户端可以直接访问数据,甚至可以将这些数据导入到Excel或Access中的OData)

  • 我有多个类型的公共属性,IQueryable但它们不会出现在WCF数据服务公开的数据列表中.

为了解决这个问题,我认为最完整的解决方案是能够将TVF称为表并从中创建一个集合.但我不知道该怎么做?!

注意 对数据库的任何更改都需要一些日志记录,因此我有存储过程来执行这些更改,因此我只需要对我的WCF数据服务的只读访问权限,并且我不希望默认设置包含在表中发布的表的所有记录.服务

Ste*_*ble 2

我认为您可以通过使用定制的数据服务提供者来定义 WCF 服务的形状来获得您想要的功能。这可能会变得非常复杂,但由于您已经有一堆 IQueryables,您可能能够使用Reflection Provider,文档对此表示:

反射提供程序公开返回实现 IQueryable 接口的类型的类中的数据。WCF 数据服务使用反射来推断这些类的数据模型,并且可以将针对资源的基于地址的查询转换为针对公开的 IQueryable 类型的基于语言集成查询 (LINQ) 的查询。

该文档链接到使用反射提供程序的“如何”。基本上,您只需创建一个具有 IQueryable 属性的伪上下文类,向数据对象添加一些属性,并将 DataService 指向伪上下文类型。(如果您使用数据库/模型优先 EF,您可能需要创建实体的部分内容以便添加属性或更新 T4 模板。)