问题
I want to expose both simple entities and joins as OData via a single WCF service. Given a domain of Lists of Artists and their Albums, I know I can have a DbContext like so:
public class PickContext: DbContext {
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<List> Lists { get; set; }
and from that I can make an OData service like this:
public class PickDataService : DataService<PickContext> {
public static void InitializeService(DataServiceConfiguration config) {
config.SetEntitySetAccessRule("Lists", EntitySetRights.AllRead);
config.SetEntitySetAccessRule("Artists", EntitySetRights.AllRead);
config.SetEntitySetAccessRule("Albums", EntitySetRights.AllRead);
I also know that I can introduce a class to flatten Lists, Artists, and Albums somewhat into a join like so:
public class PickContainer {
private PickContext pickContext=new PickContext();
public IQueryable<Foo> Foos { get; private set; }
public PickContainer() {
Foos=from a in pickContext.Albums
select new Foo {
ID=a.ID, Title=a.Title, Rating=a.Rating, Newness=a.Newness, Chance=a.Chance,
LastChosen=a.LastChosen, Acquired=a.Acquired, Media=a.Media, ArtistID=a.ArtistID,
ArtistName=a.Artist.Name, ListID=a.Artist.ListID };
}
}
and then I can create a second service to host this join entity:
public class PickService : DataService<PickContainer> {
public static void InitializeService(DataServiceConfiguration config) {
config.SetEntitySetAccessRule("Foos", EntitySetRights.AllRead);
But what I can't work out is whether there's a way to have both sets of entities in a single container, and more importantly, in a single service. Is this possible? I've played around with $expand=Artist, but my life will be easier if I wind up with a flattened model on the client. When I try to include Foos in PickContext and add it to PickDataService, I get an exception "The given name 'Foos' was not found in the entity sets."
回答1:
WCF use a specific Data Service Provider for Entity Framework. You can learn more here. Each service use only one provider. You can't mix multiple provider in one service.
回答2:
You are trying to mix use Entity Framework provider (PickContext) and Reflection provider (PickContainer) in same Service, but WCF Data Service does not support this, as you can only provide one provider for one service.
But you can archive this via Web API.
Consider set up the following controllers:
public class AlbumsController : ODataController
{
[Queryable]
public IQueryable<Album> Get()
{
return new PickContext().Albums;
}
}
public class FoosController : ODataController
{
[Queryable]
public IQueryable<Foo> Get()
{
var Foos = from a in new PickContext().Albums
select new Foo
{
ID = a.ID,
};
return Foos;
}
}
And add the following in Route config part:
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Album>("Albums");
builder.EntitySet<Foo>("Foos");
IEdmModel model = builder.GetEdmModel();
config.Routes.MapODataRoute(
routeName:"odata",
routePrefix:"odata",
model: model
);
Then you can access both under same service root:
http://host/odata/Albums
http://host/odata/Foos
来源:https://stackoverflow.com/questions/21804722/wcf-odata-dbcontext-and-joins