ansoesil’s blog

“Learning is experience. Everything else is just information.” – Albert Einstein

Behind The Scene: Astoria Data Source Control

with 22 comments

Hi

Probably some of you are confused with the declarative configuration that you need to set up when you want to use Astoria Data Source control from Intersoft DataSource™. In this post I’ll try to elaborate the things one by one so hopefully its easier to understand how the Astoria Data Source control works.

First of all let me show you one way to select data from Astoria Data Service manually. I assumed you already know how to establish Astoria Data Service, or you can always learn it from my earlier post, or from MSDN references.

astoriadatasource11

As you can see we need to do lots of things, creating the service proxy / object, create the query, call the asynchronous call. Then attached the asynchronous call back where we can grab the data then apply it to our UI control. Furthermore we’re going to need similar process for Create, Update and Delete operation which might take some time to manage it properly.

Here where Astoria Data Source tries to help, it tries to simply the CRUD operation to ADO.NET Data Service. Please see the note i put in the picture above. Those are the information we need for Astoria Data Source declarative configuration.

The Reference Namespace was defined when you set the service reference in your silverlight project.

astoriadatasource2

The Service TypeName is your ADO.NET Data Service’s Object Context where you define in your MyNorthwind.svc.cs file.

astoriadatasource31

The Service Host is basically the host that contains the ADO.NET Data Service file, while the Service Target is the actual ADO.NET Data Service file. Later when you deploy the project, you need to adjust the Service Host accordingly to where you host your application.

The Data Object TypeName is object type that available in your ADO.NET Data Service, in this case i used Northwind Database therefore I’ll have Customers, Products, Employees, etc as my Data Object TypeName.

Here is what its how the declarative configuration looks like:

astoriadatasource4

Given this info, its enough for us to help you perform CRUD operation in more elegant way. One thing you should note that you can also specified the configuration individually per AstoriaDataService, something like:

astoriadatasource5

In this configuration, the AstoriaDataService[Customers] will look to http://localhost:52026/MyNorthwind1.svc instead of http://localhost:52025/MyNorthwind.svc. So if you have multiple services you don’t need to create additional data source control and configure other integrated features, you just need to set this individual settings to each data service and you’re set.

To do Data Binding with this Astoria Data Source: Data Binding to Silverlight Data Bound Control using Intersoft Data Source(tm)

To do CRUD operation using Astoria Data Source: Performing CRUD to Silverlight Data Grid using Intersoft Data Source ™

To do Child Data Retrieval using Astoria Data Source: Performing Child Data Retrieval using Intersoft DataSource™

Next I want to show you event handlers that Astoria Data Source has, and what you can do at each event.

  • Object Creating Event
    This is called when Service Object is going to be created.

–> at this point
proxy = new MySilverlightApplication.MyServiceReference.NorthwindEntities(new Uri(“http://localhost:52025/MyNorthwind.svc”));

  • Object Created Event
    This event is called when Service Object has been created.

proxy = new MySilverlightApplication.MyServiceReference.NorthwindEntities(new Uri(“http://localhost:52025/MyNorthwind.svc”));
–> at this point

You can grab the Service Object from the event argument, and probably change some property inside it if necessary.

astoriadatasource6

  • Object Disposing Event
    This event is called when the Service Object is going to be disposed.
    Again we passed the Service Object here, just in case you need to do additional clear up before the Service Object is disposed.
  • Selecting Event
    This event is called before we perform asynchronous call to perform data selection. You can add / change additional select argument or supply your own query like what i did in Performing Child Data Retrieval using Intersoft DataSource™ .

–> at this point
serviceQuery.BeginExecute(new AsyncCallback(GetCustomersCompleted), serviceQuery);

  • Selected Event
    This event is called when the asynchronous call is finished, and the data has been retrieved.private void

GetCustomersCompleted(IAsyncResult result)
{–> at this point

In this event you can grab the data using args.ReturnValue, and probably perform additional sub query as necessary before returning it to the UI. You can also check for Exception if the ADO.NET Data Service returns an exception from args.Exception.

  • Inserting Event
    This event is called before the inserting process is executed, you can grab the actual object that going to be inserted at e.NewObjectInstance where you might want to change things if necessary.
  • Inserted Event
    This event is called after the inserting process is executed, you can grab the Exception as usual if the ADO.NET Data Service returns an exception from args.Exception. You can also grab the return object from ADO.NET Data Service using args.ReturnValue.
  • Updating Event
    This event is called before the updating process is executed, you can grab the actual object that going to be updated at e.NewObjectInstance where you might want to change things if necessary. If you supply the original object (for Concurrency checking purpose) you can grab the object using e.OldObjectInstance.
  • Updated Event
    This event is called after the updating process is executed, you can grab the Exception as usual if the ADO.NET Data Service returns an exception from args.Exception. You can also grab the return object from ADO.NET Data Service using args.ReturnValue.
  • Deleting Event
    This event is called before the deleting process is executed, you can grab the actual object that going to be deleted at e.OldObjectInstancewhere you might want to change things if necessary.
  • Deleted Event
    This event is called after the deleting process is executed, you can grab the Exception as usual if the ADO.NET Data Service returns an exception from args.Exception. You can also grab the return object from ADO.NET Data Service using args.ReturnValue.

In all of this event you have e.ServiceName to distinguish operation between AstoriaDataService, so you can target the action accordingly per service.

Thats all for now.
Hope this clear things about how Astoria Data Source control works.

Regards
Andry

Written by ansoesil

February 11, 2009 at 4:52 pm

22 Responses

Subscribe to comments with RSS.

  1. Andry, would it be possible to show us one sample of DS that consumes an XML that is sitting on the same domain as the XAP file?
    It would be great if the XML file had a field that has link to an image. This way, when the data is read, I like to see I can retrieve from DS and then attach it to different components.
    Thanks!

    Ben Hayat

    February 11, 2009 at 7:47 pm

  2. Hi Andry;

    As I was reading your recent post, one thing that came to mind was the whole notion of assigning URI at design time. If you notice the URI that was declared in XAML on reflects the local dev. machine. And it’s not a good practice, to just change the URI to hosting machine, compile and upload. Since the workflow of change -> Build -> publish is going to happen continually, it’s best to have it set in code behind at runtime. I was wondering if you recommend a way that if the app is running (XAP and service file) from a dev machine, the URI would be for localhost or if it’s running on hosting site it will get it from hosting site?

    Secondly, regarding your XML DS. Is it possible with your DS to perform CRUD against an XML file? I have a situation that the data doesn’t change often, perhaps every few months a record gets added or deleted. I was thinking of using an XML file than running a Database engine for just a few files?
    I think the XML DS is going to be popular too.
    Thanks!
    ..Ben

    Ben Hayat

    February 12, 2009 at 3:57 am

  3. [quote]As you can see we need to do lots of things, creating the service proxy / object, create the query, call the asynchronous call. Then attached the asynchronous call back where we can grab the data then apply it to our UI control. Furthermore we’re going to need similar process for Create, Update and Delete operation which might take some time to manage it properly.[/quote]

    So, if I understand you correctly, are you saying, we as the DS users do not have to deal with Astoria’s CreateQuery and Execute when trying to fetch data? It’s taken care of in your DS? Is this correct undrestanding?

    Thanks!
    ..Ben

    p.s. I think in your docs should very clearly explain what aspects of Astoria is taken care of your DS, so developers would know right off the start, what they should focus on (your DS) and things of Astoria NOT to worry about. Based on your recent posts I’m trying to draw some kind of features table that your DS is taking care of. It’s probably your most important marking piece too.

    Ben Hayat

    February 12, 2009 at 7:51 am

  4. **
    would it be possible to show us one sample of DS that consumes an XML that is sitting on the same domain as the XAP file?
    **

    Hi Ben, I’ll show you this sample later with our next release, we’re working on this feature for XML Data Source so that it can grab / download the file that reside at the same domain.

    ansoesil

    February 12, 2009 at 9:24 am

  5. **
    Since the workflow of change -> Build -> publish is going to happen continually, it’s best to have it set in code behind at runtime. I was wondering if you recommend a way that if the app is running (XAP and service file) from a dev machine, the URI would be for localhost or if it’s running on hosting site it will get it from hosting site?
    **

    Hmm probably the best way to do it is using RELEASE mark up, something like:

    #if RELEASE
    this.AstoriaDataSource1.ServiceHost = “http://servicehost”;
    #endif

    #if DEBUG
    this.AstoriaDataSource1.ServiceHost = “http://localhost:15088”;
    #endif

    Alternatively you can also put all this service settings into one file, let say “connection settings.xml”

    With structure as follows:

    and then put it on the xaml : [File:Name]

    or you can use the RELEASE mark up again as before

    #if RELEASE
    this.AstoriaDataSource1.Connection = “DeploymentConnectionSettings.xml:NorthwindDataService”
    #endif

    #if DEBUG
    this.AstoriaDataSource1.Connection = “LocalConnectionSettings.xml:NorthwindDataService”
    #endif

    **
    Secondly, regarding your XML DS. Is it possible with your DS to perform CRUD against an XML file? I have a situation that the data doesn’t change often, perhaps every few months a record gets added or deleted. I was thinking of using an XML file than running a Database engine for just a few files?
    **

    Currently we do not provide a way to edit / delete / insert data from xml data source. The reason is, if we see where the xml file located (it can be inside the xap, or in the same domain as xap), we don’t have direct access to modified it.

    I think the best way to do this is to provide a service, most likely wcf service to handle the CUD operation to xml data source. But this is just one solution that i can think of right now.

    ansoesil

    February 12, 2009 at 9:42 am

  6. **
    So, if I understand you correctly, are you saying, we as the DS users do not have to deal with Astoria’s CreateQuery and Execute when trying to fetch data? It’s taken care of in your DS? Is this correct undrestanding?
    **

    Yup pretty much, as you can see in my earlier post
    I only need to call

    DataSourceSelectArguments arguments = new DataSourceSelectArguments();
    arguments.SortExpression = “city asc”;
    AstoriaDataSource1.GetView(“Customers”).Select(arguments);

    to do the followings:

    proxy = new MySilverlightApplication.MyServiceReference.NorthwindEntities(new Uri(“http://localhost:52025/MyNorthwind.svc”));
    proxy.MergeOption = MergeOption.OverwriteChanges;

    // service query

    var query = from c in proxy.CreateQuery(“Customers”)
    orderby c.Country
    select c;

    DataServiceQuery serviceQuery =
    query as DataServiceQuery;

    // execute async request
    serviceQuery.BeginExecute(new AsyncCallback(GetCustomersCompleted), serviceQuery);

    If you ever need advance query like what i did for Child Data Retrieval you can hook it at selecting event by creating the query at that point.

    We basically try to simplify things, so that you don’t need to code bunch of similar code over and over again, but also provide extensibility so that it can covers more scenario.

    ansoesil

    February 12, 2009 at 9:49 am

  7. Thank you for well informed answers. Again, I hope your answers will become a good source to your doc to expand upon.

    Thanks again!
    ..Ben

    Ben Hayat

    February 12, 2009 at 9:35 pm

  8. Andry, when is the drop going to be? Can you give us a roadmap on DS and the presenter please? Also, did you get the two email I sent you on price and doc?

    Thanks!
    ..Ben

    Ben Hayat

    February 16, 2009 at 7:56 am

  9. Hi Ben,

    In our schedule, we’re going to release beta on early march, hope everything goes well so we can deliver it on time.

    About the price, I haven’t heard the final decision yet, so we’ll need to wait and see 🙂

    Regards
    Andry

    ansoesil

    February 16, 2009 at 9:13 am

  10. […] Behind The Scene: Astoria Data Source Control […]

  11. Any new material till the next drop?
    Thanks!
    ..Ben

    Ben Hayat

    February 22, 2009 at 10:50 pm

  12. Hi Andry;

    Have a question on “TryGetEntity” method as part of Astoria. This method is used to check to see if the entity already exist on the client side or not.

    Is this something that we could use through your datasource as well?

    This question raised another point in my mind to share with you, in case I had not brought it before.
    It would be very, very helpful to have a table with two comuns (Astoria and DS)to show what features are covered by Astoria that should be as is directly from Astoria and what features are extended by your product that we should only use your product and not bother with Astoria. This is very essential to make it crystal clear who is responsible for what.

    Ben Hayat

    February 23, 2009 at 1:47 am

  13. Hi Ben,

    We’re currently working on features for Intersoft Presenter. Some of them are extension of what we have already, some of them are new features.

    So I’ll hold the info till we have the real proof of what we’re offering 🙂

    But in the mean-time probably I’ll post how to do data binding, crud to WCF service for those who prefers it.

    ***
    Have a question on “TryGetEntity” method as part of Astoria. This method is used to check to see if the entity already exist on the client side or not.
    ***

    TryGetEntity is method from the Service Object itself (e.g. MySilverlightApplication.MyServiceReference.NorthwindEntities)

    Actually every time you perform data selection, everything will be stored on those Service Object, if you keep it around (e.g. put in global variable or static variable).

    But unfortunately in our initial design the service object won’t be keep by IS’s Astoria Data Source control. We create the service object when we want to perform data operation, then when the data operation is finished we dispose this object.

    I’ll prepare the table that describe what is covered by our data source control in the next post 🙂

    Regards
    Andry

    ansoesil

    February 23, 2009 at 1:53 pm

  14. >>But unfortunately in our initial design the service object won’t be keep by IS’s Astoria Data Source control. We create the service object when we want to perform data operation, then when the data operation is finished we dispose this object.<<

    So, you’re saying we shouldn’t count on the Service Object Data since it’s under the control of DS and not application?

    Thank you for the table. I think it will save support team many questions.

    Ben Hayat

    February 23, 2009 at 5:01 pm

  15. Hi Andry;

    I’m wondering if my following question would relate to your DS product. If it does I’d love to hear your point of view.

    I’m trying to learn how to implement MVVM pattern with SL application and since your DS becomes part of this picture, I was wondering if you have any points about it?

    Thanks!
    ..Ben

    Ben Hayat

    February 24, 2009 at 10:43 am

  16. ***
    So, you’re saying we shouldn’t count on the Service Object Data since it’s under the control of DS and not application?
    ***

    Yup, currently the DS doesn’t provide the Service Object Data, so you can’t use it. But if its desirable later, we can analyze it and do enhancement from there.

    Regards
    Andry

    ansoesil

    February 24, 2009 at 11:23 am

  17. Hi Ben

    I’ve been learning about the MVVM pattern for SL as well.

    Currently we designed the Intersoft DataSource to works with event handlers at code behind. Meaning that you need to create the DataSourceControl in the xaml page, and then call the Select method, attached the retrieved data, perform sub query, etc directly at code behind per xaml page.

    With WVVM pattern we need to separate things into Model, View and View Model.

    So with this concept, i think its better not to put the DataSource into the xaml page. Instead we can use it as Data Model that you can call from your View Model.

    In other words you can create a data model class, then create a data source control object with all its configuration. After you have this set up, you can call to this data source control from your View Model and do things accordingly.

    Hope this make sense,
    Andry

    ansoesil

    February 24, 2009 at 11:51 am

  18. Hi Andry

    ***
    So with this concept, i think its better not to put the DataSource into the xaml page. Instead we can use it as Data Model that you can call from your View Model.

    In other words you can create a data model class, then create a data source control object with all its configuration. After you have this set up, you can call to this data source control from your View Model and do things accordingly.
    ***

    That’s exactly what I thought by creating the DS in a Model, so the ViewModel can get the data from it and pass it to the View section. I’m glad we’re on the same path looking at this.
    Great, I hope you continue your research 🙂
    Thanks!

    Ben Hayat

    February 24, 2009 at 8:49 pm

  19. Andry, have you received my last two emails?

    Thanks!
    ..Ben

    Ben Hayat

    February 26, 2009 at 7:38 pm

  20. Good article with supporting details. However, I am trying to see if I can leverage the Intersoft Presenter and/or DataSource to use existing web services.

    My scenario is as follows:
    – SL requests web service asynchronously
    – web service returns data (can do JSONObject or XML) as well as column definition for grid
    – SL dynamically adds new GridPresenter to the table using the definition returned from the web service

    Is this feasible to do using the existing component build? Any good examples that show further detail on binding to a web service as opposed to static xml file?

    Dale K

    March 2, 2009 at 8:31 pm

  21. Hi Dale

    It is feasible, however you need to handle the column creation and data assignment manually after you got your “info” from your web service.

    We currently are preparing for the March 2009 CTP, which will be available in few days. I’ll give you a sample and probably step by step in later within this blog as well.

    Anyway just for a starter here’s a general overview what you need to do.

    ——————
    WebService.asmx
    ——————

    public class MyColumn
    {
    public MyColumn()
    {
    }

    public MyColumn(string dataMember, string dataType)
    {
    this.DataMember = dataMember;
    this.DataType = dataType;
    }

    public string DataMember { get; set; }
    public string DataType { get; set; }
    }

    public class PresenterInfo
    {
    public List Columns { get; set; }
    public List Customers { get; set; }
    }

    ///
    /// Summary description for WebService
    ///
    [WebService(Namespace = “http://tempuri.org/”)]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    // [System.Web.Script.Services.ScriptService]
    public class WebService : System.Web.Services.WebService
    {

    [WebMethod]
    public PresenterInfo InitializePresenter()
    {
    PresenterInfo info = new PresenterInfo();
    info.Columns = new List();
    info.Columns.Add(new MyColumn(“CustomerID”, “System.String”));
    info.Columns.Add(new MyColumn(“ContactName”, “System.String”));

    NorthwindDataContext db = new NorthwindDataContext();
    info.Customers = db.Customers.ToList();

    return info;
    }
    }

    ——————
    Page.xaml.cs
    ——————

    public Page()
    {
    InitializeComponent();

    WebServiceReference.WebServiceSoapClient client = new IntersoftPresenter_WebService.WebServiceReference.WebServiceSoapClient();
    client.InitializePresenterCompleted += new EventHandler(client_InitializePresenterCompleted);

    client.InitializePresenterAsync();
    }

    void client_InitializePresenterCompleted(object sender, IntersoftPresenter_WebService.WebServiceReference.InitializePresenterCompletedEventArgs e)
    {
    PresenterInfo info = e.Result;

    foreach(MyColumn columnInfo in info.Columns)
    {
    DataPresenterTextColumn column = new DataPresenterTextColumn();
    column.DataMemberField = columnInfo.DataMember;
    column.DataType = columnInfo.DataType;
    column.Caption = columnInfo.DataMember;

    this.GridPresenter1.RootTable.Columns.Add(column);
    }

    this.GridPresenter1.ItemsSource = info.Customers;
    }

    ———–

    Basically you can connect to any existing web service from Silverlight, you just need to add the service reference to your silverlight project and you can do things like the above code snippet.

    Call the web service : client.InitializePresenterAsync();
    And process the data retreived : client_InitializePresenterCompleted

    As you can see i assigned the column structure based on data i get from WebService, and assigned the data directly afterwards.

    Hope this clear some of the clouds. I’ll give you working samples when we release the next CTP so stay tune 🙂

    ansoesil

    March 2, 2009 at 10:16 pm

  22. Andry, FYI:

    Did you see this new post? I thought I share it with you!

    http://blogs.msdn.com/astoriateam/archive/2009/03/01/announcing-ado-net-data-services-v1-5-ctp1.aspx

    Ben Hayat

    March 3, 2009 at 11:34 am


Leave a comment