For a given entity set, say, WHO_TYPES, I want to limit the columns to the ID and the WHO_TYPE_NAME.
The entity set itself is exposed, via:
config.SetEntitySetAccessRule("WHO_TYPES", EntitySetRights.AllRead);
… so I can’t see how to do this when setting the entity/table access rules. Is it possible to write a QueryInterceptor to accomplish this? If so, how?
Another attempt I have made is to write a custom method that references a custom object:
[DataServiceKey("MY_WHO_TYPES")]
public partial class MY_WHO_TYPES
{
public MY_WHO_TYPES() { }
public int MY_WID { get; set; }
public string MY_WNAME { get; set; }
}
My custom method:
[WebGet]
public IQueryable<MY_WHO_TYPES> GetWhoTypesCustom()
{
var whoCustom = from w in this.CurrentDataSource.WHO_TYPES
select new MY_WHO_TYPES() { MY_WID = w.ID, MY_WNAME = w.WHO_TYPE_NAME };
return whoCustom.AsQueryable<MY_WHO_TYPES>();
}
With this attempt, I get the following error message:
Unable to load metadata for return type 'System.Linq.IQueryable`1[DAL.Models.MY_WHO_TYPES]' of method 'System.Linq.IQueryable`1[DAL.Models.MY_WHO_TYPES] GetWhoTypesCustom()'.
I’m feeling some sort of repository pattern coming up in a response, but I’m hoping this could be simpler.
The suggestion of using a Tuple sounds good, but I’m not quite sure how to implement it or what the return type would be:
select new { Tuple<int, string> (w.ID, w.WHO_TYPE_NAME)}; // error: Invalid anonymous type member declarator. Anonymous type members must be declared with a memeber assignment...
Next I tried simply returning an anonymous type:
[WebGet]
public IQueryable GetWhoTypesCustom()
{
var whoCustom = from w in this.CurrentDataSource.WHO_TYPES
select new { w.ID, w.WHO_TYPE_NAME };
return whoCustom;
}
The problem with this is that I get an error indicating the IQueryable type is not defined.
The simplest way to do this is to use stored procedures instead of the actual entities themselves.
This involves creating a complex type from the sproc. Define the columns that you want to be returned in the sproc and create a complex object when creating your entities.
From the *.edmx view:
That should work, but it seems there is some issue when consuming the service, where navigating to the URL in a browser shows data, but when consuming it in an application, an error is seen in the service trace log:
Configuration evaluation context not found. This is addressed in another question.However, if it’s a 1:1 field mapping in the sproc to one of the entities, in the steps above, instead of selecting a new complex type, select Entities and the matching entity and this will work fine in both cases (URL navigation an consumption).
The issue found (unable to return complex types) seems to be what the root cause of this issue, and is more accurately addressed here.