Showing posts with label DataSources. Show all posts
Showing posts with label DataSources. Show all posts

Wednesday, May 8, 2013

CLASS Services

The next version of CLASS extensions is going to be available by the end of summer with some really interesting goodies added. But, with HTML client (even before it’s official release) being in the center of interest, I feel like Silverlight extensions, are going to be soon, if not already, out of demand.
So, until I find the time to catch up with HTML client, I though on focusing more to stuff that are client implementation independent. That’s why, apart from the next version of CLASS Extensions for Silverlight clients, I plan on releasing a Server/Common side extension pack called CLASS Services.
If you are one of the blessed people Angel that purchased CLASS Extensions, you already know of File Server service included, that provides file based content access to your server.
Two more of the services that are going to be included in this new CLASS Services pack can be found in this sample I posted in MSDN. Ok, I am not crazy, I know that if I share the code no-one will buy the extensions, but these two simple (as regards to the coding effort) services, are just a part of what CLASS Services is going to include. Either way, I believe my Lightswitch community contribution, even if not as extensive and steady as other people’s, makes clear that the idea is sharing and not making money out of it.
Regarding the sample, I must underline that the application itself is just an example. And I want to stress this point, because some would say that, what the sample application displays is not DI. The idea of the sample was not to display DI in action but just to display how you bind the RIA services together, to do whatever you like. MEF is used as a DI framework by the RIA Service to provide the required functionality.
Also, I have to admit that if properly implemented, by the book, restrictions and conventions in imports and exports of MEF (or any other DI framework for that matter) would make any additional configuration (like the one my sample suggests) pointless.
Nevertheless, IMHO, you really have to be a DI purist, not to recognize the potential provided by these two services. An example: In Computer Life, we plan (George stop calling me names Smile with tongue out) to implement a generic (extension) way to support EAV model in our Lightswitch applications. It’s so obvious how useful the Domain Types RIA service will be for this implementation that I won’t even bother writing anything to prove it.
Anyway, I hope you find these two RIA services useful. I realize you have to go far beyond the “Coding is optional” motto to make good use of this kind of services, but I believe the Lightswitch development community, has already given the answer to that (not at all well-intentioned) “It’s the next MS-Access” hype…

Friday, June 22, 2012

RIAlity Issues

Recently I had to face a very frustrating issue regarding the integration of a RIA Service as a LightSwitch Datasource. I tried to find references for it in the web. I did. But none of them (at least the ones I managed to find) didn’t seem to match my case. So after solving my issue I thought sharing was a good idea…
After having implemented and tested my RIA service using a small Silverlight application I decided to add a datasource and use it. Which I did. Focusing at the part of the RIA service that caused the problem, I had a class called ImageAttachment and 2 queries exposing it. Below you can see the initial code:
   1:      [Query(IsDefault = true)]
   2:      public IQueryable<ImageAttachment> GetImageAttachments() {
   3:        return new List<ImageAttachment>().AsQueryable();
   4:      }
   5:   
   6:      public IQueryable<ImageAttachment> GetFolderItemImageAttachments(Guid? providerId, string folderId, string mailItemId) {
   7:        if (!providerId.HasValue || folderId == null || mailItemId == null)
   8:          return GetImageAttachments();
   9:        return GetAttachments(providerId.Value, folderId, mailItemId);
  10:      }



Importing the RIA Service GetFolderItemImageAttachments was properly imported as an optional query for ImageAttachment.

image

I added an ImageAttachment visual collection in a screen fetching results from GetFolderItemImageAttachments query. Everything worked smoothly. But when the time came to load the visual collection (i.e. run the query) I got an exception I hadn’t come across before neither as a LS developer nor as a Silverlight one:

Load operation failed for query ‘GetFolderItemImageAttachments’.  The remote server returned an error: NotFound.

The behavior was very strange. Although the query was recognized and imported from LS for some reason at runtime it looked like the method was not found. I placed a breakpoint at the method and it didn’t hit. The method was never called. Before doing this I was sure it was some bug of mine in the implementation that caused the RIA service to throw this generic exception. But no! The execution never reached the web method. It was then that I decided to “google” it. Looked like it was a RIA Services+LightSwitch(?) issue. All references where either not appropriate in my case or had no effect. Then I did what I usually do when I have problem I cannot solve: I scrolled to the part of code listed above and started to just stare at the code waiting for an answer. And I came to me! Why not make sure the query method IS a query? So what I did was just add the QueryAttribute to my method with no parameters:

   1:      [Query(IsDefault = true)]
   2:      public IQueryable<ImageAttachment> GetImageAttachments() {
   3:        return new List<ImageAttachment>().AsQueryable();
   4:      }
   5:   
   6:      [Query]
   7:      public IQueryable<ImageAttachment> GetFolderItemImageAttachments(Guid? providerId, string folderId, string mailItemId) {
   8:        if (!providerId.HasValue || folderId == null || mailItemId == null)
   9:          return GetImageAttachments();
  10:        return GetAttachments(providerId.Value, folderId, mailItemId);
  11:      }




I thought that if it didn’t solve the problem I surely would not cause a new one. It IS a query method after all. Why let LS infer it? And it worked.

I am quite sure I was lucky. I mean, the query was recognized either way. I cannot explain what exactly was the bug the QueryAttribute fixed. To stress my point more, I have to admit that went back to the RIA Service and I removed the attribute. Still worked! Like a deadlock resolved. Maybe only LightSwitch Team can explain. Anyhow I thought of sharing in case anyone else runs into something like this.Smile

Tuesday, February 7, 2012

Re-Views

In previous posts I made reference to views (DB or RIA) as an alternative (amongst other well-known potentials of views) to search and sort against fields that would normally be relations (lookups or however you want to call them).
From the very beginning I had an issue with SQL Server views imported to LS. LightSwitch had a very strange way to define the primary keys of the views. These “inferred” primary keys are most of the time very complex combined keys. And this is not an issue actually until you decide to add a relationship between this view (which 99% of the times has only one field as actual primary key) and another table. Then you realize this, otherwise benign, complex primary key is an issue (to say the least).
It was only recently, in this thread, after Yann Duran’s suggested reading (always to the rescue and always having something useful to contribute), that I managed to both understand how LS “infers” the Primary Key for a View and realize how one can “force” a primary key.
The bottom line is that LS decides that all not-nullable fields will be part of the inferred primary key. Not very inspired but I must admit I cannot think of anything better. So, how one can force the primary key one wants? The way is re-introducing all you not-nullable, non-key fields by cast/convert to the same data-type (or another one if needed). This way the definition of the “table”/”view” imported by LS contains all, originally not nullable fields, as nullable.
Very short example. Imagine Table Person as
Id int not null, PK
LastName nvarchar(50) not null,
FirstName nvarchar(50) null,
.
.
.
Your view’s SQL would be
select Id, CONVERT(nvarchar(50), LastName) as LastName, FirstName
from Person
Simple, dummy example just to display what I mean.
I feel I am re-inventing the wheel as this information was already out there, but in Greece we say “Επανάληψη μήτηρ μαθήσεως” or “Repetition is the mother of Learning” or something like that. Looks like we never learned much from this anyways…

P.S. After Yann's suggestion I have to note that actually this inferred primary key mechanism is Entity Framwork's native and not LightSwitch own behaviour. Although I had that in my mind I didn't make it clear here. I apologize for any missunderstanding and I thank Yann once more for the comment.

Monday, January 16, 2012

Save (is a pain in the) As

Currently being in the process of developing a business application, I came across an issue that looked harmless, but turned out to be what the title elegantly :-P implies.
Being very proud of what I can achieve in no time with LS, I had my product manager testing the application, when she ask me the simple: “How can I change something and save it as a new object with a new name?”. “It’s not implemented yet, but I am getting my hands on it right now and you will have it in no time”. What a typical developer answer!
“No time” turned out to be a full workday of experimenting trying to find out the best and most generic way to implement Save As functionality. Having an object being copied to another was something I had already implemented but I worked fine only on originals. Fetching an object to the client, modifying it somehow and then trying to copy to a new one, discard the changes of the original object and save the copy…well it was not a piece of cake, rather a pastry shop.
Creating a new object in a different instance of the dataworkspace and trying to copy ended up in a threading hell, as my object was not a simple one but having many one to many and many to many relations and threading had to be made “safe” to ensure consistency. Even if could manage to do it for the type of object requested by my product manager, the solution would be specific to this object and generalization would be a project on its own, with doubtful result.
Having the original and the copy on the same screen and context, made almost impossible to find a general way to discard changes made to the original (or any of the related objects) before saving the dataworkspace.
The final solution was rather naive, but totally generic and “LightSwitch” with only one drawback that I will mention at the end.
My datasource was an SQL Server based one. So I created a new one called myDataSourceNameCopy from the same database and also named all the entities EntityNameCopy (much better that EntityName1 suggested by default from LS. Now I had a myDataSourceName.Customer (for example) instance on my Customer Details screen and a myDataSourceNameCopy.CustomerCopy property waiting to be instantiated upon “Save As” command by the user.
A small parenthesis: one of the first contracts I designed and implemented for all the objects need was ICopyTo<TEntityType> where TEntityType : IEntityObject, which exposes a void CopyTo(TEntityType target). So Customer was already implementing ICopyTo<Customer> and what I had to do was implement ICopyTo<CustomerCopy> (and all referenced objects accordingly of course).
In order to by able to save from my screen both in myDataSourceName and myDataSourceNameCopy Ι took a look at this video tutorial. In the end when the used confirms the Save As, I save the changes in myDataSourceNameCopy, I discard the changes of myDataSourceName, close the screen, refresh the list of Customers (or whatever) and my “Saved As” Customer is there in the list of Customers ready to use. Well, I have to update two datasources every time my database changes but it’s a small price to pay, given that save as Is very important for my application.
The drawback is that I haven’t yet managed to figure out how this can be achieved with native LS datasources.
If anyone has implemented some other generic way to support Save As functionality and has to offer any ideas I would very much appreciate the comments.

Thursday, October 6, 2011

Concurrent or fast? I’d rather have both…

Did you know that concurrency provided automatically by LightSwitch might cause performance issues that you cannot easily trace?
LightSwitch uses Entity Framework’s concurrency mechanisms to ensure data consistency while 2 or more users modify the same entries. You can read about it in detail and with examples in this great (as always) post by Michael Washington.
The thing, though, is that using native data sources or SQL server imported data sources, LightSwitch applies concurrency checking to all fields and you can do nothing about it. So, what is wrong about that? The price you have to pay in performance terms is small in exchange to ensuring concurrency, one would say. Unfortunately this is not always the case. Apart from functionality issues that can easily come up (entities with last modification fields for example), there is one special but not so uncommon case that can kill your performance. Large binary fields. Images is the most common example. Checking images byte against byte with every record updated for modifications, is something that, in most cases at least, no one wants.
As in many other cases, RIA comes to the rescue. With RIA services, importing your domain objects in an EF entity model you can fully control which fields are checked for concurrency and which are not. Not only this, but also concurrency exceptions are passed-through to LightSwitch and the resulting behavior is exactly the same as if you were using native or SQL server imported data sources. This is great don’t you think…Winking smile

Wednesday, October 5, 2011

Sort This, you Light of a Switch

Did you know that LightSwitch by default cannot sort or search against lookup columns?
Sad but true. The native Data Grid of LightSwitch cannot sort or search against lookup columns. The good news is that, as always with LightSwitch, you have an option. Which is not at all bad, by the way. In non-editable grids, that is in search or list-detail screens, you can use views. Yes, database views that is. Another solution would be calculated fields, but, although simpler, performance is poor IMHO.
Views? How do I create views in LightSwitch? Well, you don’t. You cannot have views in native data sources (at least I am not aware of some way). But you can import them. Either with a SQL Server data source from an existing database, or with RIA Services data source.
Having a view containing the id of the entity (it doesn’t have to be visible) you can use it to either open the default detail screen on click, or, in the list detail scenario, remove the detail group, add the original entity’s collection query and filter it based on the selected item of the view query, or have a <EntityCollection>_SinlgeOrDefault query and bind the parameter to the view query's selected item id column. Then add a detail group for this query. You might have implementation issues you should deal with, but hey, this is a tips blog.
P.S.1 If you use or planning to use 3rd party controls your commercial data grid might solve this problem without all of the above. But If you don’t…
P.S.2 The whole truth (and nothing but the truth) is that you might have issues correctly importing views from SQL Server (regarding primary key for example, have you fixed it yet George?) so if I have to be honest, I must say RIA is the best way to go…Winking smile