LLBLGen Pro Runtime Framework supports the WCF Data Services shipped by Microsoft. The support is for .NET 4 and higher, similar to WCF Ria Services support. LLBLGen Pro Runtime Framework comes with a full Data Service Provider implementation which makes it real easy to create your own WCF Data services based on a model in Adapter or SelfServicing code.
The WCF Data Services is designed to be usable with existing Visual Studio.NET tooling. The following information describes how to define a WCF Data Services for generated code in Adapter or SelfServicing. The example below will add a service for 'Northwind', using Adapter, however you can use the same code for SelfServicing.
LLBLGen Pro WCF Data Services support is implemented in the SD.LLBLGen.Pro.ODataSupportClasses.dll assembly. This assembly supports OData v1, v2 and v3 and is compiled against v5.6.1 of the WCF Data Services Server assembly available from nuget, instead of the .NET 4 version of the same assembly. Your application will therefore need to reference this same assembly (or newer) to use ODataSupportClasses. This nuget based WCF Data Services Server assembly supports OData v1, 2 and 3.
If you need OData v4 support and thus want to have the OData Support Classes compiled against v6.x of the WCF Data Services, you have to compile the OData Support Classes yourself from the source code archive of the LLBLGen Pro Runtime Framework, which is available to you in the customer area under 'Extras'. v6.x isn't backwards compatible with OData v3 and earlier hence this limitation.
![]() |
By default, the LLBLGen Pro runtime framework setting 'ConvertNulledReferenceTypesToDefaultValue' is set to true. This results in null string fields to return the value "" instead of null. As a result, the string field will be set to "" when updating the entity instead of null and this could lead to wrong updates for these fields as "" might mean something else in your application than null. To overcome this, set 'ConvertNulledReferenceTypesToDefaultValue' to false in the project settings (in the Conventions: LLBLGen Pro Runtime Framework node) |
using System; using System.Collections.Generic; using System.Data.Services; using System.Data.Services.Common; using System.Linq; using System.ServiceModel.Web; using System.Web; using SD.LLBLGen.Pro.ODataSupportClasses; using RootNamespace.Linq; namespace MyNamespace { public class NorthwindService : LLBLGenProODataServiceBase<LinqMetaData> { // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config) { // TODO: set rules to indicate which entity sets and service operations // are visible, updatable, etc. // Examples: // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead); // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; } } }
protected override LinqMetaData CreateLinqMetaDataInstance() { // adapter return new LinqMetaData(new DataAccessAdapter()); // selfservicing: // return new LinqMetaData(); } protected override ITransactionController CreateTransactionControllerInstance() { // adapter return new DataAccessAdapter(); // selfservicing: //return new Transaction(System.Data.IsolationLevel.ReadCommitted, "Trans"); } protected override IUnitOfWorkCore CreateUnitOfWorkInstance() { // adapter return new UnitOfWork2(); // selfservicing // return new UnitOfWork(); }
protected override string ContainerName { get { return "NorthwindService"; } }
The easiest way to consume the service in a .NET application is to add a Service Reference (in VS.NET) of the service you just created. This way VS.NET will generate classes for you, one for each entity exposed by the service and a context class to work with the entity classes on the client.
If you want / have to use JSONP with the data service, e.g. because a control used on the client requires JSONP support in the WCF Data Service, please follow the following steps:
After this, the service is capable of handling $callback and $format elements properly and is able to handle and return JSon.
We did our best to support WCF Data Services in full to make sure everything in your LLBLGen Pro model/generated code is exposable through the service. However as it turned out, WCF Data Services in its current version (.NET 4 framework) has limitations and these limitations can make it a problem to expose the generated code through a service, even though the generated code works OK when used in normal .NET code. These limitations are described below.
Most of them will result in an error either when you obtain the $metadata or when you fetch data. If you run into one of these limitations, it's best to create a copy of the LLBLGen Pro project file and remove the entities/fields/types which cause a problem and re-generate the code, and use that in the service. If that's not doable, please look at WCF Ria Services instead. This other framework is also supported by LLBLGen Pro and has less limitations (but also less features in some areas).
As WCF Data Services builds an entity data model (EDM), the types are based on the EDM type system. This means that it can't deal with fields which have an Enum type. The LLBLGenProODataServiceBase class filters out fields with Enum types and all other types which aren't mappable to an EDM type. These fields don't show up in the entity exposed by the service. The types which are supported are listed in the list of DataTypes on this page: http://msdn.microsoft.com/en-us/library/dd723653.aspx. Our provider doesn't use the Reflection provider, but the same list of types applies.
A field in the primary key of an entity isn't allowed to be of type byte[]. This is a limitation of WCF Data Services, and a left-over from Entity Framework, which has the same limitation.
When generating typed views as poco classes with linq, they can be used with OData, using WCF Data Services and the OData Support Classes. However due to limitations in WCF Data Services from Microsoft, the typed views are not directly queryable, as they are defined as complex types in the OData service, not as entity types.
The main reason for that is that entity types require a PK in WCF Data Services and typed views don't have a PK. To use the typed views in OData a service method has to be added which returns an IQueryable and which has a [WebGet] attribute. It's still not possible to use orderby, paging and the like on this method due to limitations in WCF Data Services with respect to complex types, unfortunately.
The WCF Data Services client is even more limited in that it can't deal with a collection of complex types, so the service method's return type won't be consumable from a .net class if the client is used: the more low-level reader has to be used in this case.
If you select OData v1 or OData v2 using the DataServiceBehavior settings, navigators on subtypes are filtered out by the ODataSupportClasses. This is a limitation of WCF Data Services in .NET 4 / 4.5. This limitation means that if you have inheritance in your entity model, any subtype can't have a relationship with another entity, all relationships have to be defined on the root of the hierarchy. This is quite a limiting factor for many people. If you run into this, be sure to set the OData protocol to v3 using the following in the InitializeService method:
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
In LLBLGen Pro, many to many relationships are always read-only and this won't change in a WCF Data Service. To update many-to-many relationships, you have to append entities over the intermediate entity and the 1:n/m:1 relationships instead, like you'd do normally when using LLBLGen Pro code.
The WCF Data Services framework creates a projection of nested queries to implement an $Expand directive. This in general works however it goes wrong with expanded m:1/1:1 relationship navigators which are 2+ levels deep, due to a limitation in our Linq provider. Our Linq provider fetches nested queries using separate, prefetch path like queries which are merged in memory and which utilize optimizations based on parent sets. The downside is that to be able to do this, the nested query has to be configured in such a way that there's a correlation filter constructable to tie nested query to outer query. The way WCF Data Services constructs the nested queries makes this currently not possible to do, so these nested queries fail.
We'd like to thank Brian Chance for his work in this area. His templates (which used the RelfectionProvider) to bring WCF Data Services support to LLBLGen Pro were a great source of information during the development of the data source provider.