I did a lot of migrations from CRM 2011 to CRM 201X including CRM 2016 and Dynamics365. Here are my gathered suggestions/thoughts on the problems
1) Basically the organization migration that is handled by CRM Deployment Manager does its job pretty well. I usually create a staging environments on separate servers (so CRM 2013 -> CRM 2015 -> CRM 2016) make a full copy of the database, restore it on the next server and import organization using Deployment Manager. As for the customizations - it depends how old is the CRM, how many customizations it has and if it was upgraded from CRM 4.0. If the last one is true and the amount of customizations is huge - in most cases i remove all Javascripts and plugins and write them all from scratch. Although after successfull migration to CRM 2011 after Rollup 12 may make all the scripts and plugins working properly, most of the logic from CRM 4.0 can usually be achieved using some new features of CRM 2016 (not only Business Rules, which I don't like personally, but mostly Calculated Fields or Rollup Fields) and it makes no sense to keep all that stuff in some JavaScript or plugins. If the system origin is CRM 2011 then I would only audit the functionalities that can be made simpler, but usually not rewrite the whole thing, just make some adjustments. If the scripts contain OrganizationData service calls, I usually rewrite them to use webAPI - OrganizationData is going to be removed from CRM soon, so this is a good thing to do.
Of course after importing the organization to the destination environment I would apply all the modified customizations (that were made on a separate DEV environment and tested thoroughly).
2) I always use Kingswaysoft SSIS Connector for such purposes. I tested all the other tools and this is simply the most flexible, because it embraces all the power of SSIS packages and simply provides you an easy to use connector. Of course this is my personal preference, all the tools should do their job in the end.
When I migrate the data between two on-premise environments (usually in the same domain) I don't bother with migrating special fields like createdby, modifiedby, statuscode, statusreason etc. I focus only on record Ids. When I have all records created I simply update all the fields that are problematic using T-SQL scripts, because that's much faster. Of course you can't do that when migrating to Online, so this migration will take much more time (and you will not be able to migrate for example modifiedon field)
The simplified flow I always use is like that
- Create all the records without proper statuscodes (use default) and lookup values (because most likely you will not have the related record). If it's online then focus on special fields that cannot be changed later - createdon, createdby
- Update all lookups for all records (because after 1. you have all records in CRM)
- Update all statuses, if it's on-premise run all the custom scripts copying values
- Apply the customizations
3) Quite good answers were already given, Dynamics365 is simply an update for CRM 2016 (that's why it's version 8.2 not 9.0), so from CRM perspective there are not many changes. The biggest change that can be taken into consideration during upgrade is editable grid - it's very easy to prepare a view that can be editable (although it has it's drawback like no in-line record creation) which can simplify some scenarios (or will allow you to drop some custom solutions). Business Process flows are better handled, because they have separate database table, where all the important information about the process state is kept (that also introduces new SDK access to this processes) Other things are simply cosmetics, mostly for the business guys, not for developers.
4) As for the bounty question - all the apps can still be using plain old Organization.svc (by getting IOrganizationService object), which is a SOAP endpoint to CRM. There are no plans to remove this endpoint for now, so I cannot see any advantage in rewriting this application to be using webAPI (of course that's possible). XrmServiceContext is simply a wrapper over the IOrganizationService, which allows you to use it in more "Unit-of-work" way - certainly useful for retrieving data, but I don't like it as it comes to all other CRUD operations. But anyway - it is still only a wrapper, so the only thing that matters is how you obtain IOrganizationService. Back in CRM 2011 most likely you did that using OrganizatoinServiceProxy class which you instantiated using proper credentials data (like I explained here: https://mcmap.net/q/1013630/-connecting-to-crm-online-through-crm-365-plugin). Currently the suggested approach is to use Microsoft.Xrm.Tooling.Connector assembly (simply obtain it from nuget - Microsoft.CrmSdk.XrmTooling.CoreAssembly) and using CrmServiceClient together with connection string (see: https://msdn.microsoft.com/en-us/library/jj602970.aspx). This will allow you to get your IOrganizationService which you can wrap in xrmservicecontext or whatever you want. This approach is suggested, because most likely in the future, this package will start using webAPI instead of Organization.svc endpoint, so if Microsoft decides to remove or deprecate this service, your application will be still working without a problem.