Rich clients (Flex/AIR/Silverlight) & LINQ : data across the pipe

19 03 2009

I’ve blogged before about Flex & LINQ, but I’m always learning new things, and I wanted to share some of my most recent findings.

Note: this article focuses on Flex & LINQ, but it could as easily be applied to Silverlight & LINQ as well. Silverlight 3 is set to merge client & server with .NET 4.0, but I believe the issue of how much and when to send data between client & server will continue to be relevant.

First off, why LINQ?

  1. With LINQ on your server layer, you can avoid having to write your server value objects – LINQ to SQL will do that for you from your DB schema – allows you to quickly updates these objects if your schema ever changes (and let’s face it, it will). NOTE: unfortunately, there is no free & easy way to sync your LINQ to SQL context to your schema in VS2008).
  2. You can put all your SQL as strongly-typed code in your DAL rather than having to call the DB to do it via stored procs, which decouples your DB from your application, allowing you to switch databases if you ever wanted to, and keeps all your server code in one place. 
  3. Cleaner and shorter code – easier for you, easier for other developers to understand (as long as they understand LINQ 🙂 )

So, if you’ve decided to take the LINQ option and your a Flex or AIR developer, then there is good news. 

Products such as WebORB.NET and FluorineFx both support .NET 3.5 and will allow your Flex application to send Remote Objects back and forth between the two. Yes you could use Web Services to do communicate with the server, but I’m assuming you’ve read up on the performance benefits of remoting and AMF vs Web Services, and you’re opting for speed.

The question is however, how do you do it?

The LINQ to SQL tool (I’m not going to mention the ADO.NET Entities tool, which is more feature rich, but a touch more complicated) creates you a data context as you know. This remembers the actions you perform on your objects and will propagate the changes back to the DB when you “SubmitChanges()”. However, when you’re working on the Flex/.NET model, you’re now using LINQ on an middle-tier (or even an n-tier) application, and that changes things.

What changes is that the “context” will be a new instance between each request (unless you use session access to the RemoteObjects, which I won’t get into here). LINQ won’t know that you changed something outside this context, and so to Update an object in the database you will need to “Attach()” it back to the current context to save it, along with it’s original but from a new  context. (See examples below).

Now, there are plenty of articles out there on LINQ in the middle tier and LINQ with n-tier, so I won’t reinvent the wheel. What I will do is talk about strategies on how to leverage LINQ in your Flex app, and how to synchronise data.

Let’s take a think about possible methodologies for sending/receiving related object data from server to client:

  • Safety method: take a little save a little
  • Hungry method: take a little save lots
  • Greedy method: take everything save lots
  • Thrifty method: take everything save a little

I’ll use the following example to illustrate the different methods:

Example Schema

 

Safety Method

The safety method is a simple-to-follow, clear 1:1 system  – load an object when you need it, and load the associated objects as you need them. When you save data back, call the server with either one or a collection of single unrelated objects. You rely on your foreign keys to do all the loading.

All associations within the LINQ to SQL designer (DBML) need to have INTERNAL access, to prevent them being sent to the client, and so that you can still use them within the server code. 

For example: Your client wants the list of projects? It loads them simply via LINQ. Client wants the project’s list of Companies? Load them via the ProjectID. Need to save a Company, send the server the Company object with an associated ProjectID. 

 

Hungry Method

The hungry method involves retrieving just the data objects you require at the time and building up the object model on the client side, eventually sending back an object with related objects. This means you don’t have an excessive number of save calls back to the server, and you don’t rely on the foreign key, you rely on the attached object.

For example:   You may want to load all Projects within the system via LINQ, but don’t want the associated Companies, Employees or Suburbs. You then want to create a new Project and create Companies, Employees. You then call one Save() method to save the new Project, and let LINQ create the entire collection of Company and Employee records.

Now, by default, LINQ will try to send you all the related Companies, Employees and related Suburbs when you ask for the list of Projects.  You have two main options to avoid this:

  1. Change the ACCESS of the association(s) between parent and child within the DBML (LINQ to SQL) editor to INTERNAL. This means only inside the DLL could you access this property.
  2. In your server DLL, NULL any related properties before returning the data to the client. (Literally: project.Companies = null).    

Do you see the problem? Option 1 is the obvious choice but then it means you couldn’t actually send the data back to .NET because if you tried to send a Project back with Companies attached, .NET would say that Project doesn’t have the Companies property as the association as it is internal (and the exception happens during unmarshalling on the server, handled by either the WebORB or FluorineFx DLL).

The Hungry method starts to become a real issue with visibility, and unfortunately, the easiest is to follow option 2 above, which is not a good solution in my opinion.

NOTE: When saving back to the server, do NOT send back both an associated object and an associated foreign key. This will cause .NET to except. EG: If you were to save a Company with an attached Project, you couldn’t also send back Company’s ProjectID (the FK), .NET wouldn’t know which association to use. 

So, in your client code, either remove the Foreign Keys completely from the value object, or use a property getter only to get the foreign key from the association object.

 

Greedy Method

The greedy method is expensive. You are always sending and receiving all (or a lot) of the data in a single call. The advantage is, less trips between the client and server, and minimal client & server code (one Save method to do everything!).

As you can imagine, debugging the Save method can be a headache – as debugging LINQ usually is 🙂 

Now, to Update an object under the greedy method is tricky yet fun. You need to Attach() this new object to the context, along with it’s original from yet another context. 

For example: You want to load all Employees and their Suburb plus their Company and it’s Project. If you wanted to save it back, you’d need to attach it back in. 

Employee SaveEmployee(Employee e) 
{
  DataClassesDataContext context = new DataClassesDataContext();

  //if is Update
  if (e.EmployeeID > 0) 
  {
     //need to attach Employee with a NEW INSTANCE of the DataContext
     Employee oldEmployee = new DataClassesDataContext().Employees.Single( p => p.EmployeeID == e.EmployeeID);

     //now attach it
     context.Attach(e, oldEmployee);
  }
  else
  {
     context.Employees.InsertOnSubmit(e);
  }
  context.SubmitChanges();
  return e;
}

 

This can get even tricker when you’re attaching objects with children which already exist. It can require going through the children and testing their Primary Keys using the method above.

 

Thrify Method

The thrifty method involves receiving all the required data, and just sending back the minimal amount of objects back to the server for a successful save. 

To prevent data being sent back to the server once it is already in the Flex client, requires the use of the Flex metatag: [Transient]. To use Thrifty, we need to rely on Foreign Key associations as LINQ will use the FK on the insert  (just like saving in the Safety method). The advantage is that you have complete control over anything being saved into your database, which can be a real advantage in a intricate & lengthy project. 

Generally using this method, you would need to recall all of your data again, as some associations have been modified. You can try an sychronise these on the client, but it can get VERY tricky. At the very least, you’ll need to return your saved object to get it’s ID if it was just inserted.

For example: You want to load all Projects from the system, but when you save a Project, you don’t t send back it’s Companies, this property is Transient on the client and doesn’t get send back to the server. If you wanted to save a Company, you’d send back a Company object without the associated Project object, but WITH the ProjectID Foreign Key.

 

I personally use a combination of the Thrifty and the Greedy method, deciding when I want to send all the data back, and when I just want to send back an individual object. It still means however, that I need to reload ALL of my data again after a successful save of some object. 

The most important things to remember is attaching to a new context, and not sending both a foreign key and a related foreign object back to the server simultaneously – this upsets LINQ. 

More examples and further investigation to come…

Advertisements




Flex, .NET 3.5 with LINQ to SQL part 2 (synchronising from Flex to LINQ)

29 09 2008

March 2009: This post is outdated, please see the latest article on FLEX & LINQ:

https://justinjmoses.wordpress.com/2009/03/19/rich-clients-flex-air-silverlight-linq-data-across-the-pipe/

 

Right.

So, getting your objects from your .NET 3.5 Linq to SQL setup to Flex is fairly easy. Getting the changed data back and synchronised to your DB is a different story.

The great thing about LINQ is that the data you retrieve and modify in .NET will automatically sync back to the DB by calling the SubmitChanges() method on your context (Linq to SQL) object.

The problem is of course when this data comes back in from Flex, the system doesn’t know what exactly has changed.

Now, the first thing to realise is that your Value Objects in Flex should NOT have the foreign key IDs in them. Why? Because say in the Company/Employee example, if you submit a Company object back to the system, with each Employee in the list having both a CompanyID AND a Company object reference, how will the LINQ system know which is the correct reference?

These foreign IDs will try to get serialised on the remoting level and be ignored. Good. We’re dealing with object references now, and foreign key ids are useless. If I want the foreign key of some employee, I would say: EmployeeObj.Company.CompanyID

Now, in .NET, I have a “Save()” method that I want to essentially insert/update the object and all objects within in.

Using the example before, say I have a company object, and that has a list of Employees. Then if I have a Save(Company c) method, I want the company object to insert/update, and the list of employees to automatically synchronise.

You can try deleting the old object and then inserting the new

So,

SaveCompany(Company newCompany)
{

DataClassesDataContext db = new DataClassesDataContext();
if (newCompany.CompanyID > 0)
{

Company oldCompany = db.Companies.Single<Company>(c => c.CompanyID = newCompany.CompanyID);
db.Companies.DeleteOnSubmit(oldCompany);
}
db.Companies.InsertOnSubmit(newCompany);
db.SubmitChanges();
}

This will nicely handle an insert/update of the company object, but it won’t deal with your Employee objects that well. Especially when each Employee references anthor table that essentially depicts there type./

Say each Employee has a foreign key reference to EmployeeType. Employee type is a static naming table that has a set of 5 records: “Manager”, “Sales Coordinator”, “Receptionist”, “Consultant” and “Helpdesk”. Then my Employee object will have an EmployeeType property (loaded via LINQ). Now, when this goes through LINQ, I believe during the serialisation, the creation of a “new” object EmployeeType will mean that the code above will create a new EmployeeType record for the Employee. Ouch.

So even though you may have sent all the employees through LINQ to Flex via a Company object, when it comes back, even if unchanged, all these employees will have references to new EmployeeType objects.

The way to solve this is fairly easy:

foreach (Employee e in newCompany.Employees)
{
   EmployeeType type = db.EmployeeType.Single<EmployeeType>(t => t.TypeID == e.EmployeeType.TypeID);
   e.EmployeeType = type;
}

oldCompany.Employees = newCompany.Employees;

Unfortunately, it’s not an easy process to learn how exactly to handle each scenario in synching LINQ and Flex, but one thing’s for sure, it certainly makes code lighter, and a lot easier to update.





Flex, .NET 3.5 with LINQ to SQL

23 09 2008

March 2009: For more information see the latest article on FLEX & LINQ:

https://justinjmoses.wordpress.com/2009/03/19/rich-clients-flex-air-silverlight-linq-data-across-the-pipe/

——————————————————————————-

I had certainly delayed looking at LINQ for too long.

After seeing a screencast on some of the new features in ASP.NET I noticed the very handy LINQ to SQL item.

Well.

Let’s just say I’m not using strongly typed datasets anymore.

LINQ provides strongly typed access to your database (tables, views, sprocs and function) while also allowing you to query those results.

Whilst many still advocate the use of stored procs for larger and more advanced or intensive queries, at least some of the simple overhead can be reduced. Furthermore, updating your C# classes to reflect your DB is as simple as updating the LINQ to SQL item.

But the major advantage from a Flex remoting perspective is how easy it is to have all this returned data in your client.

Say I have three tables: (already linked with relationships via foreign keys)

Employee, Company & Position

I add the LINQ to SQL item to my solution. Inside, I connect the LINQ object up to the db and drag in my database objects. Voila, I have the strongly typed classes: “Employee”, “Company” and “Position”. None of this DataRow, DataTable, DataAdapter business.

Using LINQ syntax, I can do simple queries on the spot, like:

DataClassesDataContext db = new DataClassesDataContext();

var data = from e in db.Employees where e.CompanyID == someCompanyID select p;

List<Employee> employees = data.ToList<Employee>();

Now, I can return this list to either FluorineFx or WebORB and the ArrayCollection that the List is serialised into will contain an array of Employee Value Objects (my Employee.as file). Nothing special there.

BUT, the “Company” property is also provided. This is the Company property that is automatically generated in LINQ to SQL that provides the foreign key reference to the company.

This holds for all your foreign keys.

So if you want to reduce your overhead from a C# (writing classes for your db objects) and DB perspective (writing sprocs for every data call), then take a gander at .NET 3.5.

NOTE:

  • If you weren’t aware, .NET 3.5 framework is actually an addition to .NET 2.0. This means that once you install the framework on a machine, no manual IIS settings are required (as opposed to the 1.1 to 2.0 switch) to activate 3.5 on a website or virtual directory.
  • Both FluorineFx and WebORB support .NET 3.5