locked
svc with EF doesn't expose all IQueryable RRS feed

  • Question

  • In my EDM, I have an entity type Contact, and an entity type Employee which inherits Contact.

    So I have only one EntitySet: Contacts.

    I want to expose all the employees on a svc. Of course I can use an operation service but I want to expose all the employees like other entity types.

    I extend (with partial) my ObjectContext and I add a property of type IQueryable<Employee> which returns Contacts.OfType<Employee>().

    With custom model (without EF), svc exposes all the IQueryable properties. But not with EF. Is it possible to do what I want?

    Thursday, September 11, 2008 9:19 PM

Answers

  • You cannot add a top level entity set when using EF as the provider, since astoria gets the metadata from the csdl, which is fixed.

     

    If you really want to do this, the only option is to add a ServiceOperation that returns IQueryable. You need to add this method to your service class (which derives from DataService).

     

    Code Snippet

     

    [WebGet]

    public IQueryable<Customers> Employees()

    {

    return this.CurrentDataSource.Contacts.OfType<Employee>();

    }

     

     

     

    The uri will look something like this: http://localhost:34840/Northwind.svc/Employees(). (you need to have empty parenthesis at the end).

     

    Hope this helps.

    Thanks

    Pratik

    Monday, September 15, 2008 2:33 PM
    Moderator

All replies

  • You could try something similar to:

     

    1.

    http://localhost:34840/Northwind.svc/Customers?$filter=isof('NorthwindModel.Customers')

     

    Where in the isof you give the inherited type name i.e. type of Employees. And replace /Customers with the /<Base Entity Set> i.e. Contacts

     

    2.

    Another option is to use query interceptors and allow only employee objects, that would be something like:

     

           [QueryInterceptor("Contacts")]
           public Expression<Func<Contacts,bool>> OnQueryContacts()
           {
              return o => o is Employee;
           }

     

    However, with the interceptor you will never be able to query for anything but Employees i.e. this interceptor will only allow employees to pass through always.

     

    Thanks

    Waseem Basheer

    Friday, September 12, 2008 5:31 PM
    Answerer
  • 1. Yes of course but it's not what I wanted.

    2. Yes of course but in my case Contacts are Employees or CustomersContacts. So I can't use QueryInterceptor.

     

    What I want to be able to do is:

    http://localhost:34840/Northwind.svc/Employees or http://localhost:34840/Northwind.svc/CustomerContacts

     

     

    Friday, September 12, 2008 6:54 PM
  • You cannot add a top level entity set when using EF as the provider, since astoria gets the metadata from the csdl, which is fixed.

     

    If you really want to do this, the only option is to add a ServiceOperation that returns IQueryable. You need to add this method to your service class (which derives from DataService).

     

    Code Snippet

     

    [WebGet]

    public IQueryable<Customers> Employees()

    {

    return this.CurrentDataSource.Contacts.OfType<Employee>();

    }

     

     

     

    The uri will look something like this: http://localhost:34840/Northwind.svc/Employees(). (you need to have empty parenthesis at the end).

     

    Hope this helps.

    Thanks

    Pratik

    Monday, September 15, 2008 2:33 PM
    Moderator
  • Thanks.

    So I have a new question.

    Monday, September 15, 2008 2:38 PM
  • Quick update: you need not have to specify () at the end. They are optional.

     

    Thanks

    Pratik

     

    Monday, September 15, 2008 4:54 PM
    Moderator