WCF RIA Domain service will always return the IQuerable tyoe not the primitive types like int, or List. In some cases it is eminent that we need to just return the ID field which is int or List<string> customerList to the client not the whole table. The below sample will explain how to do it.
Step 1: Create the domain service by right click on the web project of the RIA Service and select New Item and select the Domain Service from the List
Step 2: Name the domain service to relevant table name in my case “CustomerService.cs”. Click on Add and the list of Tables will be displayed. Select the Customer Table. If you check Enable Editing then Insert and update methods are added to the service. Click Ok to generate the class.
Step 3: The CustomerService with the below code will be added.
[EnableClientAccess()]
public class CustomerService : LinqToEntitiesDomainService<AdventureWorksLTEntities>
{
// TODO:
// Consider constraining the results of your query method. If you need additional input you can
// add parameters to this method or create additional query methods with different names.
// To support paging you will need to add ordering to the ‘Customers’ query.
public IQueryable<Customer> GetCustomers()
{
return this.ObjectContext.Customers;
}
public void InsertCustomer(Customer customer)
{
if ((customer.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(customer, EntityState.Added);
}
else
{
this.ObjectContext.Customers.AddObject(customer);
}
}
public void UpdateCustomer(Customer currentCustomer)
{
this.ObjectContext.Customers.AttachAsModified(currentCustomer, this.ChangeSet.GetOriginal(currentCustomer));
}
public void DeleteCustomer(Customer customer)
{
if ((customer.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(customer, EntityState.Deleted);
}
else
{
this.ObjectContext.Customers.Attach(customer);
this.ObjectContext.Customers.DeleteObject(customer);
}
}
}
Step 4: Now add the new method which adds the primitive type.
The first method will return the string and the second method will return List of string.
[Invoke]
public string GetCustomerEmailId(int customerId)
{
var sal = from c in this.ObjectContext.Customers where c.CustomerID == customerId select c.EmailAddress;
return sal.FirstOrDefault().ToString();
}
[Invoke]
public List<string> GetEmailList(string customerName)
{
var salList = from c in this.ObjectContext.Customers where c.FirstName.StartsWith(customerName) select c.EmailAddress;
return salList.ToList();
}
Step 5: Build the solution to create a proxy file for the client. Now navigate to the silverlight project and add the below code for calling the service. Basically in the below code i have declared 2 property EmailId and EmailList. Inherited the MainPage from INotifyPropertyChanged to trigger the property change for Xaml to update. Then called the webservice and set these property.
using Projectname.Web.Services;
using System.ServiceModel.DomainServices.Client;
public partial class MainPage : Page, INotifyPropertyChanged
{
private string _email = string.Empty;
private List<string> _emailList = null;
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public MainPage()
{
InitializeComponent();
this.DataContext = this;
MyCustomerContext ctx = new CustomerContext();
ctx.GetCustomerEmailId(2, EmailIdCompleted,null);
}
public string EmailID
{
get
{
return _email;
}
set
{
_email = value;
this.RaisePropertyChanged("EmailID");
}
}
public List<string> EmailList
{
get
{
return _emailList;
}
set
{
_emailList = value;
this.RaisePropertyChanged("EmailList");
}
}
// Executes when the user navigates to this page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void exitApp_Click(object sender, RoutedEventArgs e)
{
try
{
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void GetEmailsButton_Click(object sender, RoutedEventArgs e)
{
try
{
CustomerContext ctx = new CustomerContext();
ctx.GetEmailList(NameTextBox.Text, EmailListCompleted, null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void EmailListCompleted(InvokeOperation<IEnumerable<string>> args)
{
this.EmailList = args.Value.ToList();
}
private void EmailIdCompleted(InvokeOperation<string> args)
{
this.EmailID = args.Value.ToString();
}
}
Step 6: Add the same to the XAML for the Binding
<navigation:Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="1024" d:DesignHeight="768"
Title="CustomerByDate Page" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" xmlns:my="clr-namespace:BusinessApplication2.Web.Models" xmlns:my1="clr-namespace:BusinessApplication2.Web.Services" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
<Grid x:Name="LayoutRoot">
<StackPanel>
<Border BorderBrush="Gray" Margin="2,2,2,2" BorderThickness="2,2,2,2" Background="Black" HorizontalAlignment="Stretch" Height="40">
<TextBlock Text="Sample using simple data type value return on RIA Service" FontSize="20" Foreground="White" />
</Border>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center" Text="Enter name to search:" Margin="5,0,5,0" />
<TextBox Text="{Binding Path=CustomerName}" Margin="5,0,5,0" Width="163" Name="NameTextBox"/>
<Button Margin="5,0,5,0" Name="GetEmailsButton" Click="GetEmailsButton_Click" Width="111" Height="30" Content="Get Emails"/>
<ComboBox Name="CustomerList" ItemsSource="{Binding EmailList}" Width="247" Height="25" Margin="2,0,5,0"/>
<TextBlock VerticalAlignment="Center" Text="Email Address = " Margin="5,0,5,0" />
<TextBox Text="{Binding Path=EmailID}" Margin="5,0,5,0" Width="163"/>
</StackPanel>
</StackPanel>
</Grid>
</navigation:Page>
Below is the Executed code.