Contact Me

Contact Us
For an informal discussion

Everyone's business is different. Our business is software - ask where we can help.
eMail: john at appsolo.com

Archive for June, 2010

RIA services and Productivity

Thursday, June 17th, 2010

We at Appsolo Ltd have been building a non-standard Business application in RIA Services. I just though I would share some things that have arisen during the latter stage of development.

The procedure for setting up an Entity Domain Model (.edmx)

image thumb RIA services and Productivity

has been well documented here on the appsolo blog and elsewhere, as has been the argument of using Views on the database or DTO on the web server for joins.

For Joins where you want all the fields from the two tables or for a small number of records of small spans there is also the technique of using the Include statement which is part of Linq to EF in the Domain Service Class

and not forgetting to put in the tag in the Metadata part of the Domain Services class

   1: public IQueryable<Node> GetNodesByID(int n)

   2:         {

   3:             IQueryable<Node> NodesByMaster;

   4:             NodesByMaster = this.ObjectContext.Nodes.Include("Arc").Where(node => node.NodeID == n);

   5:             return NodesByMaster;

   6:         }

   1: [MetadataTypeAttribute(typeof(Node.NodeMetadata))]

   2:     public partial class Node

   3:     {

  14:         internal sealed class NodeMetadata

  15:         {

  16:  

  18:             private NodeMetadata()

  19:             {

  20:             }

  21:  

  22:             [Include]

  23:             public Arc Arc { get; set; }

  24:  

  25:             public int ArcID { get; set; }

  26:  

  27:             public Nullable<bool> IsRoot { get; set; }

  28:  

  29:             public int NodeID { get; set; }

  30:  

  31:             public NodeMaster NodeMaster { get; set; }

  32:  

  33:             public Nullable<bool> Terminal { get; set; }

  34:         }

  35:     }

Linq to SQL does not work too well in the domain class being probably better suited to being used in the Entity Data Model Designer.cs code as the Entity objects that are returned from the EDM do not translate too easily into IQueryables.

A further annoyance is that it is not well documented, is the importance of the Allow Edits box is checked when you are using the Wizard to set up the Domain service class. This is of particular importance if you have to change the Data Model in the Database regularly as you invariably have to with application development in the early stage of flux. If you do not delete and recreate the domain data source and just update the the EDM by right clicking on it then you do not get Entity objects that are Editable. Surely Editable should be the default. Especially as you can change the behaviour on the client or front domain service side. The code that dictates which entities are editable (produced by the Wizard) is buried in some .g.cs files and not immediately available. Well not to me anyway. If someone knows were it is can they post a comment please. This leads to unpredictable behaviour on the Silverlight client side as it does not throw an error or even a warning on binding, works on reads, but crashes the Browser when trying to do an edit through a domain data source linked via a domain service query and Entity Objects to tables in the database.

So the procedure if you make changes in the database is to drop the domain service and the EDM and set them up again. But if you do this then you will loose any customised queries that you have written in the Domain service class and indeed any metadata attributes you may have added in the Domain.metadata.cs a partial solution we have applied at Appsolo is to use a partial class of the domain service class

TaxFullDbDom.cs

   1: public partial class TaxFullDbDom : LinqToEntitiesDomainService<db1084688_TaxonomyEntities>

   2: {

   3:  

   4:     // TODO:

   5:     // Consider constraining the results of your query method.  If you need additional input you can

   6:     // add parameters to this method or create additional query methods with different names.

   7:     // To support paging you will need to add ordering to the 'Arcs' query.

   8:     public IQueryable<Arc> GetArcs()

   9:     {

  10:         return this.ObjectContext.Arcs;

  11:     }

  12:  

TaxDomExtra.cs

   1: public partial class TaxFullDbDom : LinqToEntitiesDomainService<db1084688_TaxonomyEntities>

   2:     {

   3:         //[Query]

   4:         // Also changed return type from IQueryable<Arc>

   5:         public Arc GetArcsByID(int aID)

   6:         {

   7:             return this.ObjectContext.Arcs.SingleOrDefault(a => a.ArcID == aID);

   8:         }

 

At last a sensible

Now while this will solve the problem of the deletion and re-creation of the Domain Service Class and the EDM it will not protect the Meta-Data attribute information. So lets be careful out there.

RIA could be a very productive framework to do the donkey work for Silverlight and others and yes it is only out since 2009 and is only now officially in Version 1.0 having spent some time in Beta and RC and the after all the alternative is writing loads WCF data contract code. So it’s probably still worth the time if you can come to grips with the complexity of the RIA framework. We’ve spent a lot of time trying to figure out the intricacies of a poorly but improving documented RIA services. That’s all the time I have. Comments?

 

P.

Silverlight 4 Training Resources

Saturday, June 5th, 2010

image Silverlight 4 Training Resources Within Microsoft, it’s well acknowledged that Silverlight 3 –> 4 was a big move. Most of what was called for post-SL3 to make SL4 market-ready was delivered. Remember SL3 didn’t even do proper printing so there was a drive to make SL grow up – quickly. Thankfully, there are some good resources to help explore the space. I sometimes forget that Channel 9 do more than just interviews. A good case-in-point is this comprehensive training kit on SL4, complete with 25 hours of video across 8 targeted modules covering such key areas as RIA, MEF, authentication, and printing.

PagedCollectionView with Entity Framework

Thursday, June 3rd, 2010

I always liked CollectionViews in WPF. It worked well with binding. For example, when you bind an ItemsControl (e.g. ListBox) to an IEnumerable collection, a default CollectionView is created. Most folk aren’t aware of its existence but it’s there nonetheless. Once you summon up that CollectionView, you can apply sorting and filtering operations – nothing complicated but the bang per buck is high.

In a previous post, I looked at how to effect joins through Entity Framework (EF) and concluded that DTOs (Data Transfer Objects) were the way to go. Regardless of how you pull the data down, it’s likely that the UI will want to apply some client-side sorting or filtering on the fly. There’s little point round-tripping back to the server for a re-query and pulling down all that data again. Enter PagedCollectionView:

dc.Load<TaxKey>(dc.GetTaxKeysAndAuthorsQuery(), LoadOperation =>
                {
                    taxKeyListBox.DataContext = LoadOperation.Entities;
                }, null);
            PagedCollectionView pcv = (lbxRecentlyUpdated.DataContext as PagedCollectionView);
            if (pcv!=null) pcv.SortDescriptions.Add(new SortDescription("TaxKeyAuthorName", ListSortDirection.Descending)); 

By wrapping the query results in a PagedCollectionView, you can then add (for different levels of sorting) multiple SortDescriptions (or GroupDescriptions). All this is handled client-side, quickly.

Entity Framework limitations

Wednesday, June 2nd, 2010

Entity Framework (EF) is the latest in a long line of DAL (Data Access Layers). It kicked LINQ-to-SQL firmly to touch and much is promised by it. It dove-tails reasonably with RIA Services (RIA) too. However, once you’ve watch one or two (or in my case, around 50) tutorials/videos on RIA/EF, you’ll see a trend – lots of full table access bound to a data grid. There’s a reason for that and it has a lot to do with neat DomainDataSource packaged code which hides (read – buries) the supporting code. Take for example, the (not-unreasonable) need to join some fields from one table with some from another. EF can do this using either Entity-SQL (yup, another data query language) or LINQ-to-SQL (including using lambda expressions). Okay, this is (somewhat) straight-forward.

However, RIA services (or WCF if that’s your bag) can’t send back anonymous types. So, say you do a Join on the EF and have a new view to return – you can’t. There are a few work-arounds.

Alternatives….

Work with SQL Views on SQL Server

Essentially, you script some Views at the back-end. These Views are imported to the EDMX file, effectively as a table (i.e. entity). The EDMX in case you don’t know is an XML definition of a conceptual model, a storage model, and the mapping between these models. An .edmx file also contains information that is used by the ADO.NET Entity Data Model Designer (Entity Designer) to render a model graphically. This imported View (from the database) is easily queried by EF and is effectively seen as a table (read, Entity) by EF.

Downsides? Well, if you want a custom view of your data, you have to head over to the database and write up another View, then (explicitly, but easily) update the EDMX in Visual Studio. This isn’t ideal since even if your database model is now stable, you’re likely (during development) to need different views of the data. I always saw LINQ-to-SQL (or any successor like EF) being the ideal vehicle for just this kind of thing. There’s worse to follow – these Views are read-only. To submit changes through these Views (using SubmitChanges()), you need to use SPROCS and import these as functions. This is a manual process and requires you to map the parameters of your SPROC (as well as return types). Additionally, there are issues around dependencies when deleting through a View.

EF-style View (aka Defining Query or QueryView)

This requires editing of the EDMX-xml file and given that this can be explicitly updated by changes to the database, this worries me. In any case, the approach is an order more difficult than tripping back to create a View on the database. If interested, Julie Lerman has an excellent discussion on how to do this though she refers to this as creating a QueryView whereas MSDN has this as ‘Adding a Defining Query’.

DTOs (Data Transfer Objects)

This approach is less than the open-heart surgery of the previous approach. You’ll be familiar with the creation of various queries on the DomainContext (i.e. DomainService on the client-side):

public IQueryable<TaxKey> GetTaxKeysAndAuthors()
        {
            return this.ObjectContext.TaxKeys.Include("Author").OrderBy(k => k.TaxKeyName);
        }

For example, the above query from the DomainService (on the Web project), pulls down a join on the TaxKey table and the Author table. This query was actually the genesis for my investigation. The Author table has a Picture field that (can) holds an image which could be large and isn’t always required. However, in RIA Services you’ll see that the return type is IQueryable<TaxKey> – only legitimate entities can be returned. So, even though EF will let me do a join on certain fields from certain tables, the anonymous table that is created by any Join can’t be returned. This should be obvious since if we have to specify the return type, then the new class won’t be anonymous!

image thumb 4F6534101 thumb Entity Framework limitationsThe workaround here is to create a DTO – data transfer object (well, actually a class). Sometimes referred to as a Presentation Model, this involves creating a new set of classes on the server-side (web project). Here’s one of mine to handle the Join between the TaxKey and Author tables mentioned earlier.

namespace tax_sil4_net35.Web
{
    public class TaxKeyAuthorPicture
    {
        [Key]
        public int TaxKeyID { get; set; }
        public string TaxKeyName { get; set; }
        public string TaxKeyAuthorName { get; set; }
        public byte[] AuthorPicture { get; set; }
    }
}

This now gets around the problem we had earlier where we couldn’t return anonymous types – we now have actual types (i.e. classes) to return so the earlier query method could now return: public IQueryable<TaxKeyAuthorPicture> GetTaxKeysAndAuthors()

This class can be annotated similar to the EF entity classes so we can do certain validation on the properties. Brad Abrams has a good post on this approach as does Fredrik Normen in his post (model diagram opposite credited). Here’s the DomainService query method that populates the collection for return to the client-side for viewing:

public IQueryable<TaxKeyAuthorPicture> GetTaxKeysAndAuthorsRecentlyUpdated()
        {
           return from t in ObjectContext.TaxKeys
                   .Include("Authors")
                   select new TaxKeyAuthorPicture()
                   {
                       TaxKeyID = t.TaxKeyID,
                       TaxKeyAuthorName = t.Author.AuthorName,
                       TaxKeyName = t.TaxKeyName,
                       AuthorPicture = t.Author.Picture
                   };
        }

As you can see, I’m still using Include since it makes joining easy and that’s what EF is all about. I’m content that only those fields that I need are surfaced however and that should reduce traffic to the client. The new DTO class (TaxKeyAuthorPicture) does add some additional code and isn’t especially flexible but it is the best of the alternatives I’ve explored. Here’s the XAML item template that I then bind to at the interface:

<ListBox x:Name="lbxRecentlyUpdated" toolkit:DockPanel.Dock="Top" FontSize="18" Background="{x:Null}"
                             BorderBrush="{x:Null}" ItemsSource="{Binding }">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Source="{Binding AuthorPicture, Converter={StaticResource ByteArrayToBitMapConverter}}" Stretch="UniformToFill" HorizontalAlignment="Left" MaxWidth="50" MaxHeight="50" />
                                        <TextBlock Text="{Binding TaxKeyName}" FontSize="20" Foreground="Gold" Margin="5,0" HorizontalAlignment="Left"></TextBlock>
                                        <TextBlock Text="{Binding TaxKeyAuthorName}" Margin="5,0" FontStyle="Italic" HorizontalAlignment="Left"></TextBlock>
                                        <TextBlock Text="{Binding TaxKeyChange, StringFormat=\{0:d\}}" Margin="5,0" FontSize="12" HorizontalAlignment="Left"/>
                                    </StackPanel>
                                </DataTemplate>
                             </ListBox.ItemTemplate>
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <Setter Property="HorizontalContentAlignment" Value="Right"></Setter>
                            </Style>
                        </ListBox.ItemContainerStyle>
                    </ListBox>

So, to recap. Create a simple DTO class at the server project. Write a typical DomainService query to select the needed fields (even across tables). This creates a collection of DTO objects which are then queried at the client-side and bound through the View (xaml). This way, the SubmitChanges() convenience to persist changes back to the database is preserved.

Overall, my impression of EF is flawed. Or maybe, it’s just the interaction with RIA that sullied my opinion. Either way, shifting data back/forth to a remote server should be easier than this.

Storing image in SQL database using RIA

Tuesday, June 1st, 2010

Our recent project calls for the uploading of images from local storage for storing remotely on a SQL server instance that we manage via RIA services. Here’s how we do it.

<Image Grid.Column="1" Grid.Row="3" Height="150" HorizontalAlignment="Left" Margin="3" Name="pictureImage"
                   Source="{Binding Path=Picture, Converter={StaticResource ByteArrayToBitMapConverter}}" Stretch="Fill" VerticalAlignment="Center" Width="200" />

The Image control above is bound to the Picture property of the Author class (a proxy for the Author table in the database). The Image control is actually in a Grid whose DataContext is bound to a parent data grid’s SelectedItem. The Converter used is to create a BitmapImage object from the byte array returned from the database:

 

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var binaryData = (byte[])value;

            if (binaryData == null)
            {
                return null;
            }

            BitmapImage bitmap = null;

            if (IsJpegOrPngImage(binaryData))
            {
                Stream stream = null;

                try
                {
                    stream = new MemoryStream(binaryData);
                    bitmap = new BitmapImage();
                    bitmap.SetSource(stream);
                }
                catch (Exception)
                {
                    bitmap = null;
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                }
            }

            return bitmap;
        }

        private static bool IsJpegOrPngImage(byte[] binaryData)
        {
            if (binaryData.Length > 2)
            {
                if (binaryData[0].Equals(0XFF) && binaryData[1].Equals(0XD8))
                {
                    return true;
                }

                if (binaryData[0].Equals(0X89) && binaryData[1].Equals(0X50))
                {
                    return true;
                }
            }

            return false;
        }

Now for how to get the image file into the database in the first place. There is a Load button on the UI that polls the user to choose an image file:

private void Load_Image_Click(object sender, RoutedEventArgs e)
        {
            var dialog = new OpenFileDialog
            {
                Filter = "Image files(*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png|All Files (*.*)|*.*"
                ,
                FilterIndex = 1
            };

            if (dialog.ShowDialog() == true)
            {
                using (Stream fileStream = dialog.File.OpenRead())
                {
                    System.IO.Stream stream = dialog.File.OpenRead();
                    byte[] bitArray = new byte[stream.Length];
                    stream.Read(bitArray, 0, bitArray.Length);

                    // pick the current record from the datagrid (or CurrentItem of DataForm is using that)
                    var rec = authorDataGrid.SelectedItem as Author;
                    rec.Picture = bitArray;
                    stream.Close();
                };
            }
        }

The file identified is opened as a FileStream and a (suitably-sized) byte array created to hold the data read from the stream. The bound record is called up from the parent DataGrid and cast appropriately. The byte[] is then assigned to the Picture field of that record. Thanks to binding, the UI control (i.e. Image control) that is bound to that property is notified and you’ll see the update on-screen.

1 pages

latest news

UI Flow

Posted on Tuesday, 16th April, 2013

Often, we use wire-framing or mock-up tools (like the good guys at Balsamiq) to help communicate design ideas between developers as well as to clients. However, there is a need for something more efficient to aid communication of possible user interface flows through our emerging application. This communication is for internal use typically and doesn’t [...]

Testimonials

Excellent design skills

Posted on Sunday, 2nd May, 2010

We at Taxonomy.ie are happy to be associated with Appsolo and look forward to further work together.

follow me

twitter facebook delicious

AppsoloLtd. VAT No. IE97548691 - Copyright © 2010.