I have DbContext subclass
ReportingContext : DbContext
As I'm doing simple CRUD I then created a WCF Data service to expose my DbSet...
public class ReportService : DataService<ReportingContext>
I have been able to use the ReportingContext directly to do 'table splitting'. Basically use 2 entities (ReportLayout and ReportLayoutData) which both use a single table. I was able to configure this using the fluent API. Everything worked fine in Unit tests as I was able to return ReportLayouts and only load ReportLayoutData when they were accessed.
My problems started when I tried to do this through a WCF Data Service, OData version 5.6 - using the DataServiceContext class. Returning ReportLayouts work fine, but trying to lazy load the dependent data has not been possible so far. I have tried different things:
Calling Include via a service method actually worked when I debugged the service directly and checked the generated sql - 2 separate queries as for the unit test. However, the service simply did not include the ReportLayoutData property in its returned properties when viewed in the browser and I got client side errors relating to the missing property.
[WebGet] public IQueryable<ReportLayout> GetReportsByID(string ids) { var ints = GetInts(ids); return CurrentDataSource.Reports.Include("LayoutData").Where(x => ints.Contains(x.ReportLayoutID)).AsQueryable(); } private static int[] GetInts(string ids) { return ids.Split(",".ToCharArray()).Select(x => Convert.ToInt32(x)).ToArray(); }
I tried to use DataServiceContext.Expand - $expand - and this failed with various errors as I tried slighly different arguments
I tried calling Execute, various problems
I turned the ReportLayoutData property into an IQueryable even though it is a 1-1 relationship and now it says ReportLayoutData is not a property of ReportLayout when running the EF specific unit test that previously worked fine.
My question: is it possible to Lazy Load via a WCF Data service in this manner or should I just expose 2 collections and resolve the results into a single object on the client? If it is possible I would just like to see the basic pattern - a couple of related entities, fluent API declarations and the DataService code. Thanks for any help.
EDIT
I am currently being plagued by the error:
A property with name 'LayoutData' on type 'ReportLayout' has kind 'Structural', but it is expected to be of kind 'Navigation'.
Although there is no problem retrieving the data in the browser: ReportService.svc/Reports()?$expand=LayoutData
partial stack trace:
Microsoft.Data.OData.ReaderValidationUtils.ValidateNavigationPropertyDefined(String propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings) at Microsoft.Data.OData.Atom.ODataAtomEntryAndFeedDeserializer.TryReadNavigationLinkInEntry(IODataAtomReaderEntryState entryState, String linkRelation, String linkHRef)
I was able to remove the above error by not exposing 2 dbSets through the service. Will consider a service operation to return what I need from EF, shame it isn't so elegant.
In the end my solution was to split the table so as to create a navigation property exposed as an ICollection
I was able to implement queries such as Reports/ReportService.svc/Reports(1) $expand=LayoutData as a result (AddQueryOption("$expand", "LayoutData") and wrote a service method to do this for multiples.
[WebGet]
public IQueryable<ReportLayout> GetReportsByID(string ids)
I only exposed a single Dbset via the service - the children are not accessible directly.
Client side updates to the dependent entities can be achieved using the DataServiceContext methods:
AddObject, AddLink
AttachTo, UpdateObject, AttachLink //UpdateObject on the child ensures the entity state changes to modified (see DataServiceContext.Entites collection).
In retrospect I probably did not need to split the table but do not have time to play with this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.