Reputation: 15
I'm doing a project that reads from an oracle database. I have used Silverlight RIA, and autogenerated DomainService since I'm not too concerned about structuring as I only worry about displaying the data.
My question is, that when I use the domaindatasource from the XAML, and use fiddler for debugging the WCF service and its calls, the first set of data from the table of useraccounts contains 2 million rows, and the DomainService times out.
Now I have tried increasing the timeout of the service to 20 mins, but still no avail, I get the error:
Load operation failed for query "GETUA_USERACCOUNTS". The http request to has exceeded the alloted timeout
Also out of the total 9 tables that I use, 3 tables have around 2 million rows, what would be the best method to approach this problem?
Upvotes: 1
Views: 1503
Reputation: 51
I had similar issue and to handle this i created stored procedures on my database to do the work and only spit back the information i needed. There is not a lot of info on adding stored procedures to RIA but here is a shot on what i know works.
in your domain service add a public method that returns the result list.
public IQueryable<FWCUser> UpdateFWCUserWithUserProfileID(int userProfileID, int fwcUserID)
{
return this.ObjectContext.UpdateFWCUserWithUserProfileID(userProfileID, fwcUserID).AsQueryable();
}
build your project and call the method as needed from code behind
FWCDomainContext context = new FWCDomainContext();
context.Load(context.UpdateFWCUserWithUserProfileIDQuery(num1, num2), Completed, null);
Upvotes: 0
Reputation: 2698
To continue where TomTom left off, and Red asked, do your data filtering / processing on the server, before returning the results (Psuedocode)
public IQueriable<UserDTO> GetUserAccountDetails(string UserID)
{
DataSet oneBazillionRows = SQLServer.GetAllUserRows();
// LINQ to the rescue
return from user in oneBillionRows
where user.ID = UserID;
}
and your comsumer:
public void GetUserInfo()
{
ServiceContext context = new ServiceContext();
context.Load<UserDTO>(ServiceContext.GetUserAccountDetailsQuery(), load =>
{
// do some work here
//like signalling the call is complete
// or storing the data in your View Model
}, null);
}
You consumer will then only recieve the one data row. The basic form is like so:
public IQueriable<ReturnType> WebService(Parameter parameter, ...)
{
// Do all your work here, return minimal results
}
Consider: Invariably, the sever is going to be a lot beefier than your client machine. Let it do all the work of filtering / sorting / preprocessing results, and have it hand over minimal data. You will find your RIA implementations become much more snappy.
Upvotes: 0
Reputation: 13576
Use the ToTraceString method...
http://msdn.microsoft.com/en-us/library/system.data.objects.objectquery.totracestring.aspx
...or an Oracle profiling tool to determine the SQL statement that is being used and confirm that it takes a long time to execute.
Use query optimization techniques such as adding indexes to speed it up.
Alternatively, write a stored procedure that returns the required result in a more efficient manner.
Upvotes: 1
Reputation: 599
You should use a DataPager, see here: http://www.silverlightshow.net/items/Creating-applications-with-.NET-RIA-Services-Part-4-Adding-a-DomainDataSource.aspx
<navigation:Page x:Class="WebAdministrationTool.ManageUsers"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
xmlns:local="..."
xmlns:validation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm">
<Grid x:Name="LayoutRoot">
<data:DataGrid x:Name="UsersGrid"
IsReadOnly="True"
AutoGenerateColumns="True"
ItemsSource="{Binding Data, ElementName=MyDataSource}" />
<validation:DataPager x:Name="UsersPager"
PageSize="10"
Source="{Binding Data, ElementName=MyDataSource}" />
<ria:DomainDataSource x:Name="MyDataSource" LoadMethodName="LoadHugeAmountOfRows">
<ria:DomainDataSource.DomainContext>
<local:MyDomainContext />
</ria:DomainDataSource.DomainContext>
</ria:DomainDataSource>
</Grid>
</navigation:Page>
Upvotes: 0