Files to look at:
- Customer.cs (VB: Customer.vb)
- Program.cs (VB: Program.vb)
- Service1.svc.cs (VB: Service1.svc.vb)
- Web.config (VB: Web.config)
- Service1.svc.cs (VB: Service1.svc.vb)
- Web.config (VB: Web.config)
Scenario:
In the How to connect to a remote data service instead of using a direct database connection example we described how to connect to the WCF service via console application.
If you want to take advantages of XPO data caching using this solution, the only difference is in using the ICachedDataStore interface and the CachedDataStoreService base service class that implements this interface.
Steps to implement
1. Create a data service and console applications as described in the How to connect to a remote data service instead of using a direct database connection example.
2. Modify the service class as shown in the WCFService1\Service1 code file: use the CachedDataStoreService as base class, create a connection provide and data store.
3. Modify the web.configfile as shown in the WCFService1\web.config file.
There is no need to modify the client part since the service name has not been changed, and in addition, the “data caching domain” of our service is automatically detected by XPO.
It is easy to configure which tables should be cached and which ones shouldn't using the following code from the Service1 code file:
C#DataCacheRoot dataCacheRoot = new DataCacheRoot(dataStore)
dataCacheRoot.Configure(new DataCacheConfiguration(DataCacheConfigurationCaching.InList, "Customer")
MainDataStore = dataCacheRoot;
Visual BasicDim dataCacheRoot As New DataCacheRoot(dataStore)
dataCacheRoot.Configure(New DataCacheConfiguration(DataCacheConfigurationCaching.InList, "Customer"))
MainDataStore = dataCacheRoot
This approach is useful for tables, which are frequently changed.
4. Create a data caching service based on the SqlDependency feature of the MS SQL Server. This approach is demonstrated in the WCFService2.Service1.xx file.
Important notes
If you are using an XAF client, then in the simplest case, you can just set the XafApplication.ConnectionString to the address of your data store service (http://localhost:55777/Service1.svc). Refer to the Connect an XAF Application to a Database Provider help article for more details.
Troubleshooting
- If WCF throws the "Entity is too large" error, you can apply a standard solution from StackOverFlow: http://stackoverflow.com/questions/10122957/
- If WCF throws the "The maximum string content length quota (8192) has been exceeded while reading XML data. " error, you can extend bindings in the following manner:
XML<bindings>
<basicHttpBinding>
<binding name="ServicesBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed" >
<readerQuotas maxDepth="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
See The maximum string content length quota (8192) has been exceeded while reading XML data
See also:
How to connect to a remote data service instead of using a direct database connection
How to implement a distributed object layer service working via WCF
How to connect to a remote data service from a Silverlight application
How to connect to remote data store and configure WCF end point programmatically
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using DevExpress.Xpo;
namespace ConsoleApplication1 {
public class Customer : XPObject {
public Customer(Session session) : base(session) { }
string _CompanyName;
public string CompanyName {
get { return _CompanyName; }
set { SetPropertyValue("CompanyName", ref _CompanyName, value); }
}
string _CompanyAddress;
public string CompanyAddress {
get { return _CompanyAddress; }
set { SetPropertyValue("CompanyAddress", ref _CompanyAddress, value); }
}
string _ContactName;
public string ContactName {
get { return _ContactName; }
set { SetPropertyValue("ContactName", ref _ContactName, value); }
}
string _Country;
public string Country {
get { return _Country; }
set { SetPropertyValue("Country", ref _Country, value); }
}
string _Phone;
public string Phone {
get { return _Phone; }
set { SetPropertyValue("Phone", ref _Phone, value); }
}
}
}
C#using System;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.Data.Filtering;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
XpoDefault.DataLayer = XpoDefault.GetDataLayer("http://localhost:55777/Service1.svc",
AutoCreateOption.DatabaseAndSchema);
XpoDefault.Session = null;
using (UnitOfWork uow = new UnitOfWork())
{
if (uow.FindObject(typeof(Customer), new BinaryOperator("ContactName", "Alex Smith", BinaryOperatorType.Equal)) == null)
{
Customer custAlex = new Customer(uow);
custAlex.ContactName = "Alex Smith";
custAlex.CompanyName = "DevExpress";
custAlex.Save();
Customer Tom = new Customer(uow);
Tom.ContactName = "Tom Jensen";
Tom.CompanyName = "ExpressIT";
Tom.Save();
uow.CommitChanges();
}
using (XPCollection<Customer> customers = new XPCollection<Customer>(uow))
{
foreach (Customer customer in customers)
{
Console.WriteLine("Company Name = {0}; ContactName = {1}", customer.CompanyName, customer.ContactName);
}
}
}
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}
C#using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.Xpo.DB.Helpers;
namespace WcfService1 {
public class Service1 : CachedDataStoreService {
public static ICachedDataStore MainDataStore;
static Service1() {
string connectionString = MSSqlConnectionProvider.GetConnectionString("localhost", "ServiceDB");
IDataStore dataStore = XpoDefault.GetConnectionProvider(connectionString, AutoCreateOption.DatabaseAndSchema);
DataCacheRoot dataCacheRoot = new DataCacheRoot(dataStore);
dataCacheRoot.Configure(new DataCacheConfiguration(DataCacheConfigurationCaching.InList, "Customer"));
MainDataStore = dataCacheRoot;
}
public Service1() : base(MainDataStore) { }
}
}
Code<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings />
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="DevExpress.Xpo.DB.ICachedDataStoreService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
C#using System;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.Xpo.DB.Helpers;
namespace WcfService1 {
public class Service1 : CachedDataStoreService {
public static ICachedDataStore MainDataStore;
static Service1() {
string connectionString = MSSqlConnectionProvider.GetConnectionString("localhost", "ServiceDB");
MSSqlConnectionProvider dataStore = (MSSqlConnectionProvider)XpoDefault.GetConnectionProvider(
connectionString,
AutoCreateOption.DatabaseAndSchema
);
IDisposable[] objectsToDispose;
MainDataStore = (ICachedDataStore)MSSql2005SqlDependencyCacheRoot.CreateSqlDependencyCacheRoot(
dataStore,
new DataCacheConfiguration(DataCacheConfigurationCaching.InList, "Customer"),
out objectsToDispose
);
}
public Service1() : base(MainDataStore) { }
}
}
Code<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings />
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="DevExpress.Xpo.DB.ICachedDataStoreService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>