CRM Development

Solutionist has designed the architecture for a new CRM system for use in the medical imaging industry.

Wednesday 11 March 2015

Why does my DataTable merge not work?

I was recently looking and some older DataTable code.
We were trying to merge an updated DataRow into an existing DataTable
But... it was having non of it - the changes didn't go in.

After some hunting it turned out that the RowState of both the existing and updated rows was "Modified".
So the merge didn't know what to do - what takes precedence?

The solution was to call AcceptChanges() on the existing DataTable before merging in the new data.
AccepChanges sets the RowState to Unchanged and the merge now knows what to do.

Job done!

Monday 16 July 2012

Asynchronous WCF using the generated service interface

Using Asynchronous WCF in an IoC style presents an interesting challenge.


Normal examples show that you can call async WCF something like this...
      Service1Client iService1 = new Service1Client();
      iService1.GetDataCompleted += iService1_GetDataCompleted;
      iService1.GetDataAsync();



i.e. you declare the service client implementation, specify the callback and make the async call.


But... what if you want to inject the client reference, for example (using Ninject):
[Inject]
IService1 iService1 {get; set;}

where Service1 is the interface.
Well, you find that the xxxCompleted event and xxxAsync method are not available on the interface. Ouch!
But, all is not lost...
You do have two other methods... Beginxxxx and Endxxxx and you can use them as in the example below. In the Beginxxxx method you specify the callback and in the callback you can get hold of the result by calling Endxxxx


Note that in the example below, I haven't injected the Service client, but I am using the interface, IService1. The code produces the following output (with the "Waited" appearing after the calling thread has slept for 5 seconds) :

    Making call
   Got result
   You entered: 200
   Waited

    public class Program
    {
        private static void Main(string[] args)
        {
            MakeAsynchronousCall(200);
        }
 
        private static void MakeAsynchronousCall(int value)
        {
            IService1 iService1 = new Service1Client();
 
            AsyncCallback aSyncCallBack =
                delegate(IAsyncResult result)
                    {
                        try
                        {
                            Console.WriteLine("Got result");
                            var i = iService1.EndGetData(result);
 
                            Console.WriteLine(i);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    };
 
            try
            {
                Console.WriteLine("Making call");
                iService1.BeginGetData(value, aSyncCallBack, iService1);
 
                Thread.Sleep(5000);
 
                Console.WriteLine("Waited");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

The Server-side code is :
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

Thursday 23 February 2012

Primary Keys in Entity Framework and Sync Framework - Part 2

In Part 1 we considered various options when it came to using Microsoft Sync Framework with Entity Framework.

After a certain amount of pain we seem to have got to something approaching a settled condition.
  1. We didn't want IDs that were GUIDs as this would make them unreadable. So, we are keeping Primary keys as simple ID columns.
  2. Because of this, we went for a solution that would reseed the local tables on each client to a known range. After each synchronisation, the tables would be reseeded to the correct value. That way entries created on the client/server would have different IDs and wouldn't clash
  3. We had to use SQL Server Express on the clients.
Number (3) above is a long story...

  • SQL Compact 4 won't play nicely with Entity Framework or the Sync Framework (Link here and here )
  • SQL Compact 3.5 wouldn't play nicely with the various items - follow this link and see the section "Limitations of SQL Server compact" - basically it can't:
    • "support entities with server-generated keys or values when it is used with the Entity Framework ".
There's a lot of other things that SQL server compact can't do - including supporting stored procedures. So that's how we ended up back at SQL Server Express.

I hope this gives you a flavour of the sort of things to consider when looking at data replication on SQL Server.

You're going to ask why didn't we use SQL Server Merge Replication - that's another story and another post...

Wednesday 22 February 2012

Architecture Note

A short note on architectures for WCF-based solutions - we've found this works for us.


All classes that are being passed across the wire must be serialisable and each property must be annotated.

The WCF service is nothing more than a thin facade on top of a call to Business Logic. 
In fact it's a one-to-one relationship to the Business Logic calls... The Service layer just exposes the business logic so that it can be used in creating bindings, etc.


Business Logic - as they say, it "does the business" and calls the data access.layer.
Data Access Layer - we're using Repository pattern with Entity Framework.

Throughout, we've using IoC (Ninject) to hook data access repositories into the Business Layer and Business Logic into the Service Layer. This has meant inserting Ninject into the WCF factory pipeline - see this post.

OK, you may ask why create a WCF facade on top of the business logic?

Well, doing this lets you create clean classes and "unit" tests for the business logic without  bothered about annotations, etc for WCF.
It also means that the Business Logic layer becomes a re-usable component - where you don't have to include WCF-related annotations and dlls.

Thursday 2 February 2012

How to get a WPF TextBox to update its ViewModel binding variable

A short post:

Scenario:
You're using MVVM and have bound a textbox to a string ViewModel property - in TwoWay mode.

You have a button that is only to be enabled when that string property is not null/empty. 

Problem: 
You type in the textbox, but the button remains firmly disabled until the textbox loses focus.
Only at that point is the string's PropertyChanged event raised.

Solution:
(Taken from  http://betaforums.silverlight.net/forums/t/103695.aspx )
Do the following on the TextBox's TextChanged event:
      void summaryTextBox_TextChanged(object sender, TextChangedEventArgs e)
      {
          TextBox txCtl = (TextBox)sender;
          if (txCtl != null)
          {
              var be = txCtl.GetBindingExpression(TextBox.TextProperty);
              if (be != null)
              {
                  be.UpdateSource();
              }
          }
       }
This will force the PropertyChanged event to be raised whenever the text is changed - and your button will be enabled as soon as you start typing in the TextBox.

Wednesday 1 February 2012

More .NET IoC - Using Ninject in WCF Services

I've seen other postings about this, but thought I'd add my own 2p-worth since I had to struggle a bit to get it working.

The basic idea is to use Ninject in the WCF pipeline and get WCF use Ninject to create the service. Then you can take advantage of Ninject's IoC to manage dependencies.

I used the base Ninject and the Ninject Web and Wcf extensions - all available via NuGet.

To integrate ninject into the WCF service pipeline, create a "normal" WCF service but add the following to the .svc file

Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" 


So, the file would look something like:


<%@ ServiceHost Language="C#" Debug="true" Service="WcfService.GeneralService" 
CodeBehind="GeneralService.svc.cs" 
Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>


Then you can inject dependencies into the service as needed as follows:


[Inject]
public IUsersRepository _repository { private get; set; }

Now we're assuming that you're using a WCF application project - so, to initialise Ninject correctly you need to make changes to the WCF project Global.asax file as follows:


  1. Make Global extend NinjectWcfApplication   (from Ninject.Extensions.Wcf)
  2. Implement and override CreateKernel - so the file looks like this:

    public class Global : NinjectWcfApplication

    {
    // Other methods omitted for clarity...
 
        protected override Ninject.IKernel CreateKernel()
        {
            IKernel k =  new StandardKernel(new ServiceModule());
            return k;
        }
    }


Now the ServiceModule is a Ninject module that would look something like:


    public class ServiceModule : NinjectModule
    {
        public override void Load()
        {
            Bind().To();
        }
    }


Notice that we're binding the IUsersRepository to the UsersRepository implementation.

Doing this will enable Ninject to do its magic in the WCF service above where it is injected.

When Service is invoked, the Ninject factory will instantiate the class and so be able to use the module bindings to pull in the correct interface implementations.

Notice that you don't need to change service bindings, etc. 

Thursday 29 December 2011

Primary Keys in Entity Framework and Sync Framework

Hold on - we're going for a walk on the wild side! It will take a few minutes to read - but it's a thriller...

This is a summary of what I've discovered after a bit of research - hopefully it will help other developers/architects out.

As part of a project I'm looking at creating a SQL server replicated architecture... and need to avoid clashes in the PK. The icing on the cake is that we're using Entity Framework heavily in the project for data access.

Exhibit 1 ... http://msdn.microsoft.com/en-us/library/bb726011.aspx

This article gives a few options about choosing a suitable Primary key in replication scenarios:

1. Using a GUID
2. Pk that includes a node ID
3. Natural keys

OK.... starting from the bottom up...

  • Natural Keys won't work for our project. Full stop
  • A PK that includes a Node ID - means adding a column and giving each client  a Node ID. Not the end of the world, but... doesn't feel right...
  • GUID... sounds good, or is it?

Enter
Exhibit 2 - http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/
Yes, it's all true... I tried it and had to hack the EF model XML to include the correct attribute to get it to work. And, Yes, doing an update loses the change.
Yes, it's a feature and yes, it's not pleasant - it would mean after every update hacking the XML to find all the relevant GUID PKs and adding in the attribute. I'm sure we could automate it by some clever searching and replacing, but it's not right.

Also, Enter
Exhibits 3, 4, 5 and 6
http://www.eggheadcafe.com/tutorials/sql-server/d662b371-ed27-481c-aee0-ebe7cf2d9fad/why-guids-are-not-a-good-idea-for-sql-server-primary-keys.aspx

http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html

http://www.simple-talk.com/sql/database-administration/the-identity-crisis-in-replication/

http://sqlblogcasts.com/blogs/martinbell/archive/2009/05/25/GUID-Fragmentation-in-SQL-Server.aspx


From this set of links you start to see that GUIDs are good, but come with a number of caveats.

Also using newsequentialid() - doesn't necessarily generate sequential GUIDs - I tried this. If you do a number of inserts close together then you do get them, but not always. 
So, you then can potentially have the performance issues.
Also, the space issue is relevant for us - since we're looking to replicate to SQL server compact.

Alternatives?

First off,
well we could use a normal ID (int) column and change the seed value for each client.
E.g. The Server has a seed of 10,000000
Client 1 has a seed of 20, 000000,
Client 2 has a seed of 30, 000000 etc

So, each client would be able to make 9,999,999 inserts before a conflict and we'd have a limit of 214(X2) users because we could have negative numbers as well.

Lets just do some maths....
The max value of an int is +/-2,147,483647. 
If you're really worried about conflicts you could go for using a bigint as the ID column, then you could have something like 9223327036850 clients! The seeds could then be something like 100,000000, 200000000, 300000000, etc so 99,999,999 inserts before a conflict - which should be enough for a lifetime - e.g. one insert a second would take you 1157 days. 100 inserts a day would take over 2500 years.
If you were using the the smaller int then 100 inserts a day would last over 250 years!

That means changing the seed on each client appropriately.

Now, there are ways of doing this:
http://www.techrepublic.com/blog/datacenter/how-do-i-reseed-a-sql-server-identity-column/406
but it seems there a some gotchas that you have to be aware of:
http://geekswithblogs.net/argot/archive/2009/10/18/sync-framework-common-practise-of-ado.net.aspx


Basically, you have to store and remember seed values before/after synchronisation.

You'd keep a list of seed values for each client. So any time you get a  new client the first sync would also download its seed value.

This solution has a certain appeal, because:

a. it leaves the PK alone as a single ID column
b. The replication mechanism takes care of the seeding/reseeding.
c. Entity Framework designer won't throw any wobblies.

Next alternative... 

Go back to a compound PK, ID plus a Node ID.
a. Entity Framework should cope with this.
b. Replication mechanism should be a bit simpler.
But... it means infecting the database with the replication details i.e. the Node ID and artificially creating a more complex PK. So, you can't just go
select * from Users where ID = 10.

Another thought....


This is horrible I think, but has a certain "something" about it!

Leave the PKs alone completely - simple ID column with an int.
Then code for the PK conflicts in the sync framework - as it will detect PK conflicts. 
So, we write logic that will do something like:
- determine of the inserted record exists on the server 
- if not, then add it (generating a new record/PK) then remove it from the client and
- resync the client to pull down the "new" record but with the updated PK.

You'd have to write this sort of thing to cover various scenarios and it may/would be table-specific - but what if we replicating a lot of tables?


Summing up...


We're looking at  either the compound PK or the different seed values.
We're going to try some stuff out - probably the different seed values first as that leaves the EF model alone completely - and I'll try and report back how it went.