Telerik OpenAccess Classic

Telerik OpenAccess ORM Send comments on this topic.
How to: Integrate OpenAccess with ADO.NET Data Services on the server
Programmer's Guide > OpenAccess ORM Classic (Old API) > OpenAccess Tasks > Integration and Installation > How to: Integrate OpenAccess with ADO.NET Data Services on the server

Glossary Item Box

This documentation article is a legacy resource describing the functionality of the deprecated OpenAccess Classic only. The contemporary documentation of Telerik OpenAccess ORM is available here.

Telerik OpenAccess ORM supports  ADO.NET Data Services. The base class OpenAccessDataContext that is delivered as a source code with our distribution, can be used to inherit a custom entity container implementation that exposes IQeriable endpoints required by the ADO.NET Data Services to fetch the data from the server. This is possible because Telerik OpenAccess ORM has extensive LINQ support implementation that runs smoothly against 6 databases, and it is developed even further on a continuous basis.

The aim of this topic is to explain how you can create a simple web application using Telerik OpenAccess ORM and Microsoft ADO.NET Data Services. This topic is focused on the server-side of the application where Telerik OpenAccess ORM integrates with the ADO.NET Data Services.

 

First we need a data model reversed with Telerik OpenAccess ORM. You can find about how to Create a New Data Model With Telerik OpenAccess ORM or you can use one already prepared as a starting point. For the purposes of this example we used the well known model for the NorthWind database.

 

1. Decide which entity sets are to be exposed by the data context.

Currently Telerik OpenAccess ORM does not include UI tool (wizard) to auto-generate the entity container from the data meta-model. This will be introduced in our future releases. Until then you will have to add manually the IQueriable end-points to the inherited and customized OpenAccessDataContext instance.

 2. Define the keys for the exposed classes using the DataServiceKey attributes on top of them. This example demonstrates  how this should be accomplished for the OrderDetail object (Northwind database) which also has a composite key:

C# Copy Code
([DataServiceKey(new string[]{"OrderID","ProductID"})])
VB.NET Copy Code
((DataServiceKey(New String(){"OrderID","ProductID"})))

3. Implementing the OpenAccessDataContext:

C# Copy Code
public partial class OADataContext : IDisposable
{
   
// Fields
   
IObjectScope scope = null;
   
public OADataContext()
   {
       
this.scope = this.ProvideScope();
   }
   
public OADataContext(IObjectScope scope)
   {
       
this.scope = scope;
   }
   
public virtual IObjectScope Scope
   {
       get
       {
           
if (this.scope == null)
           {
               
// Attempt to get the Scope
               
this.scope = this.ProvideScope();
           }
           
return this.scope;
       }
   }
   
protected virtual IObjectScope ProvideScope()
   {
       IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
       scope.TransactionProperties.AutomaticBegin = true;
       
return scope;
   }
   #region IDisposable Members
   
public void Dispose()
   {
       
if (scope != null)
       {
           scope.Dispose();
           scope =
null;
       }
   }
   #endregion
}
VB.NET Copy Code
Partial Public Class OADataContext
 Implements IDisposable
 ' Fields
 Private scope_Renamed As IObjectScope = Nothing
 Public Sub New()
  Me.scope_Renamed = Me.ProvideScope()
 End Sub
 Public Sub New(ByVal scope As IObjectScope)
  Me.scope_Renamed = scope
 End Sub
 Public Overridable ReadOnly Property Scope() As IObjectScope
  Get
   If Me.scope_Renamed Is Nothing Then
    ' Attempt to get the Scope
    Me.scope_Renamed = Me.ProvideScope()
   End If
   Return Me.scope_Renamed
  End Get
 End Property
 Protected Overridable Function ProvideScope() As IObjectScope
  Dim scope As IObjectScope = ObjectScopeProvider1.GetNewObjectScope()
  scope.TransactionProperties.AutomaticBegin = True
  Return scope
 End Function
 #Region "IDisposable Members"
 Public Sub Dispose()
  If scope_Renamed IsNot Nothing Then
   scope_Renamed.Dispose()
   scope_Renamed = Nothing
  End If
 End Sub
 #End Region
End Class

4. Inherit from the Ado.Net Data Services DataService class like:

C# Copy Code
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class OADataService : DataService<OADataContext>
{
   
protected override void HandleException(HandleExceptionArgs args)
   {
       
base.HandleException(args);
   }
   
// This method is called only once to initialize service-wide policies.
   
//We overide it to enable all CRUD operations by setting EntitySetRights.All
   
public static void InitializeService(IDataServiceConfiguration config)
   {
       config.SetEntitySetAccessRule(
"*", EntitySetRights.All);
   }
}
VB.NET Copy Code
<System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults := True)> _
Public Class OADataService
 Inherits DataService(Of OADataContext)
 Protected Overrides Sub HandleException(ByVal args As HandleExceptionArgs)
  MyBase.HandleException(args)
 End Sub
 ' This method is called only once to initialize service-wide policies.
 'We overide it to enable all CRUD operations by setting EntitySetRights.All
 Public Shared Sub InitializeService(ByVal config As IDataServiceConfiguration)
  config.SetEntitySetAccessRule("*", EntitySetRights.All)
 End Sub
End Class

 

You can easily generate a DataService stub to be modified, using the provided wizard with .NET 3.5 SP1.

You have to take account for the operations you require on the server-side, thus providing the required rights to the service. The System.ServiceModel.ServiceBehavior attributes are used to define the rights.

5. Implementing the IUpdatable interface for the data context:

C# Copy Code
#region IUpdatable Members
public object CreateResource(string containerName, string fullTypeName)
{
   Type t = Type.GetType(fullTypeName);
   Debug.Assert(t !=
null);  // assume can find type
   
object resource = Activator.CreateInstance(t);
   Scope.Add(resource);
   
return resource;
}
public object GetResource(IQueryable query, string fullTypeName)
{
   
object resource = null;
   
foreach (object o in query)
   {
       
if (resource != null)
       {
           
throw new Exception("Expected a single response");
       }
       resource = o;
   }
   
if (resource == null)
       
return new Exceptions.NoSuchObjectException("Object cannot be found.", null);
   
if (fullTypeName != null && resource.GetType() != Type.GetType(fullTypeName))
       
throw new Exception("Unexpected type for resource");
   
return resource;
}
public object ResetResource(object resource)
{
   Debug.Assert(resource !=
null);
   Scope.Refresh(resource);
   
return resource;
}
public void SetValue(object targetResource, string propertyName, object propertyValue)
{
   PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
   
if (pi == null)
       
throw new Exception("Can't find property");
   pi.SetValue(targetResource, propertyValue,
null);
}
public object GetValue(object targetResource, string propertyName)
{
   PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
   
if (pi == null)
       
throw new Exception("Can't find property");
   
return pi.GetValue(targetResource, null);
}
public void SetReference(object targetResource, string propertyName, object propertyValue)
{
   SetValue(targetResource, propertyName, propertyValue);
}
public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
   PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
   
if (pi == null)
       
throw new Exception("Can't find property");
   IList collection = (IList)pi.GetValue(targetResource,
null);
   collection.Add(resourceToBeAdded);
}
public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
{
   PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
   
if (pi == null)
       
throw new Exception("Can't find property");
   IList collection = (IList)pi.GetValue(targetResource,
null);
   collection.Remove(resourceToBeRemoved);
}
public void DeleteResource(object targetResource)
{
   Scope.Remove(targetResource);
}
public void SaveChanges()
{
   Scope.Transaction.Commit();
}
public object ResolveResource(object resource)
{
   Scope.Retrieve(resource);
   
return resource;
}
public void ClearChanges()
{
   Scope.Transaction.Rollback();
}
#endregion  
VB.NET Copy Code
#Region "IUpdatable Members"
Public Function CreateResource(ByVal containerName As String, ByVal fullTypeName As String) As Object
 Dim t As Type = Type.GetType(fullTypeName)
 Debug.Assert(t IsNot Nothing) ' assume can find type
 Dim resource As Object = Activator.CreateInstance(t)
 Scope.Add(resource)
 Return resource
End Function
Public Function GetResource(ByVal query As IQueryable, ByVal fullTypeName As String) As Object
 Dim resource As Object = Nothing
 For Each o As Object In query
  If resource IsNot Nothing Then
   Throw New Exception("Expected a single response")
  End If
  resource = o
 Next o
 If resource Is Nothing Then
  Return New Exceptions.NoSuchObjectException("Object cannot be found.", Nothing)
 End If
 If fullTypeName IsNot Nothing AndAlso resource.GetType() IsNot Type.GetType(fullTypeName) Then
  Throw New Exception("Unexpected type for resource")
 End If
 Return resource
End Function
Public Function ResetResource(ByVal resource As Object) As Object
 Debug.Assert(resource IsNot Nothing)
 Scope.Refresh(resource)
 Return resource
End Function
Public Sub SetValue(ByVal targetResource As Object, ByVal propertyName As String, ByVal propertyValue As Object)
 Dim pi As PropertyInfo = targetResource.GetType().GetProperty(propertyName)
 If pi Is Nothing Then
  Throw New Exception("Can't find property")
 End If
 pi.SetValue(targetResource, propertyValue, Nothing)
End Sub
Public Function GetValue(ByVal targetResource As Object, ByVal propertyName As String) As Object
 Dim pi As PropertyInfo = targetResource.GetType().GetProperty(propertyName)
 If pi Is Nothing Then
  Throw New Exception("Can't find property")
 End If
 Return pi.GetValue(targetResource, Nothing)
End Function
Public Sub SetReference(ByVal targetResource As Object, ByVal propertyName As String, ByVal propertyValue As Object)
 SetValue(targetResource, propertyName, propertyValue)
End Sub
Public Sub AddReferenceToCollection(ByVal targetResource As Object, ByVal propertyName As String, ByVal resourceToBeAdded As Object)
 Dim pi As PropertyInfo = targetResource.GetType().GetProperty(propertyName)
 If pi Is Nothing Then
  Throw New Exception("Can't find property")
 End If
 Dim collection As IList = CType(pi.GetValue(targetResource, Nothing), IList)
 collection.Add(resourceToBeAdded)
End Sub
Public Sub RemoveReferenceFromCollection(ByVal targetResource As Object, ByVal propertyName As String, ByVal resourceToBeRemoved As Object)
 Dim pi As PropertyInfo = targetResource.GetType().GetProperty(propertyName)
 If pi Is Nothing Then
  Throw New Exception("Can't find property")
 End If
 Dim collection As IList = CType(pi.GetValue(targetResource, Nothing), IList)
 collection.Remove(resourceToBeRemoved)
End Sub
Public Sub DeleteResource(ByVal targetResource As Object)
 Scope.Remove(targetResource)
End Sub
Public Sub SaveChanges()
 Scope.Transaction.Commit()
End Sub
Public Function ResolveResource(ByVal resource As Object) As Object
 Scope.Retrieve(resource)
 Return resource
End Function
Public Sub ClearChanges()
 Scope.Transaction.Rollback()
End Sub
#End Region
Starting from Telerik OpenAccess ORM 2009.2.701.X version the OpenAccessDataContext is also implemented as an assembly with the name Telerik.OpenAccess.40.dll. It requires references to Ado.Net Data Services assemblies and is compiled against .NET 3.5 SP1