如何公开具有 OData 服务的派生类和成员的多层模型?
我正在尝试公开一个可用于 OData
服务的模型。我当前采用的方法大致如下:
1) 在模型中定义一个类来公开 IQueryable 集合,例如:
public class MyEntities
{
public IQueryable<Customer> Customers
{
get
{
return DataManager.GetCustomers().AsQueryable<Customer>();
}
}
public IQueryable<User> Users
{
get
{
return DataManager.GetUsers().AsQueryable<User>();
}
}
}
2) 设置 WCF DataService可查询集合类,例如:
public class MyDataService : DataService<MyEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
config.SetEntitySetAccessRule("Users", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
我使用此方法遇到了 3 个问题和/或限制:
1) 我无法将任何派生类集合添加到 IQueryable
列表中。
2) 我必须应用IgnoreProperties
属性来隐藏从基类型派生的任何成员。
3) 我无法阻止 OData 服务访问不需要的实体并导致错误。例如,我只希望公开 BLL 层对象,但似乎模型的反映远远超出了我添加到可查询列表中的类的成员,并选取了所有 DAL 类,导致错误未定义,并且还与 BLL 类同名。 BLL 类成员没有到 DAL 类的链接。至少,我希望完全忽略这些类。
任何有关如何解决这些问题的指示将不胜感激。我应该对此采取不同的方法吗?例如,我应该直接在模型集合中实现 IQueryable
吗?
谢谢。
I'm trying to expose a model to be available for OData
services. The approach I'm currently taking is along the lines of:
1) Defining a class in the model to expose IQueryable
collections such as:
public class MyEntities
{
public IQueryable<Customer> Customers
{
get
{
return DataManager.GetCustomers().AsQueryable<Customer>();
}
}
public IQueryable<User> Users
{
get
{
return DataManager.GetUsers().AsQueryable<User>();
}
}
}
2) Set up a WCF DataService
with the queryable collection class such as:
public class MyDataService : DataService<MyEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
config.SetEntitySetAccessRule("Users", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
I'm running into 3 issues and/or limitations with this approach:
1) I'm unable to add any derived class collections to the IQueryable
lists.
2) I must apply the IgnoreProperties
attribute to hide any members that are derived from a base type.
3) I'm unable to prevent unwanted entities from being accessed by the OData
service and causing errors. For example, I only want BLL layer objects to be exposed, but it seems like the model is being reflected far beyond the members of the classes I added to the queryable list, and picking up all the DAL classes, causing errors being undefined and also having the same name as the BLL classes. There are no links to DAL classes from BLL class members. At the very least, I would like to have these classes ignored altogether.
Any pointers on how to address any of these issues would be greatly appreciated. Should I be doing a different approach on this? For example, should I implement IQueryable
directly in my model collections?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在使用的反射提供程序旨在遍历所有公共类型/属性。因此,#3,甚至可能是#2(我不完全明白问题所在)是设计使然的。
#1 也是设计使然,但出于不同的原因 - 反射提供程序只能为每种类型层次结构公开一个实体集。它不支持所谓的“MEST”(每种类型多个实体集),因为它不知道选择哪一个。它需要实体类型和实体集之间一对一的映射。
反射提供程序适用于“易于”设置的简单服务。它绝对不是为定制而设计的。
如果您想要更好的控制,那么您需要自定义提供程序,它可以直接实现(如果它基于现有的 CLR 类,那么并不难),或者通过某个库(如上面评论中建议的库)实现。
The reflection provider which you're using is designed to walk all public types/properties. So the #3 and probably even #2 (which I don't fully understand what's the problem) are by design because of that.
#1 is also by design but for a different reason - the reflection provider can only expose one entity set for each type hierarchy. It doesn't support so called "MEST" (Multiple Entity Sets per Type), because it would not know which one to pick. It needs a 1 to 1 mapping between entity types and entity sets.
The reflection provider is meant for simple services which are "Easy" to setup. It's definitely not designed for customizations.
If you want greater control, then you need custom provider, which can be either implemented directly (if it's based on existing CLR classes it's not that hard), or through some library, like the one suggested in the comments above.
反射提供程序并非旨在处理具有大量继承和其他依赖性的丰富数据模型。我最终构建了一个自定义提供程序,可以根据 Alex James 在 创建数据服务提供者。
下面提供了包含 3 个 CLR 类的示例实现:
ResidentialCustomer
、Customer
和User
。ResidentialCustomer
扩展了Customer
,Customer
有一个User
列表,并且User
有返回到客户
的引用。DataContext
类的接口,例如:用于实现
IDataServiceMetadataProvider
的类,例如:用于实现
IDataServiceQueryProvider
的类,例如:用于实现 < code>IDataServiceUpdateProvider 例如:
实现
IServiceProvider
的类,例如:DataContext
类保存 CLR 集合并连接服务操作,例如:然后,创建您的数据服务使用自定义数据服务类和您的数据上下文,例如:
大量连接,但一旦掌握了窍门就非常简单。
The reflection provider is not designed to handle rich data models with a fair amount of inheritance and other dependences. I ended up building a custom provider that could handle queries, updates, inheritance, and relationships based on Alex James' excellent blog post on Creating a Data Service Provider.
An example implementation with 3 CLR classes:
ResidentialCustomer
,Customer
, andUser
is provided below.ResidentialCustomer
extendsCustomer
,Customer
has a list ofUser
s, andUser
has a reference back toCustomer
.An interface for
DataContext
classes such as:A class to implement
IDataServiceMetadataProvider
such as:A class to implement
IDataServiceQueryProvider
such as:A class to implement
IDataServiceUpdateProvider
such as:A class to implement
IServiceProvider
such as:The
DataContext
class holds the CLR collections and wires up the service operations such as:Then, create your data service using the custom data service class and your data context, such as:
Lots of wiring up, but pretty straightforward once you've got the hang of it.