Heute hat mich ein typisches Migrationsprojekt erreicht. Eine Marketinganwendung des Kunden soll durch CRM 2011. Dafür ist es zunächst notwendig, die Daten in CRM zu importieren. Erst danach sollen eventuell fehlende Features, etc. besprochen/entwickelt werden.
Heute zeige ich euch, wie man mittels den von CRM zur Verfügung gestellten Webservice-Schnittstellen Firmen aus einer SQL-Datenbank möglichst einfach in CRM importieren kann.
Um den Zugriff auf den SQL-Server so einfach wie möglich zu halten, habe ich mich dafür entschieden auf ADO.NET Entity Data Model zu setzen und habe dem Model sämtliche Tabellen der Quell-Datenbank hinzugefügt.
Nun lässt sich im C# Code ganz einfach auf die Datenbank zugreifen, z.B.
conventoEntities context = new conventoEntities(); var firmen = (from p in context.Tbl_Firmen orderby p.Firmenname1 select p);
Im nächsten Schritt habe ich die notwendigen CRM-Webservices hinzugefügt. Im nachfolgenden Beispiel wird das Discovery und das Organization-Webservice benötigt. Eine genauere Beschreibung der Services findet ihr u.a. hier:
http://technet.microsoft.com/de-ch/library/gg309557(en-us).aspx
http://technet.microsoft.com/de-ch/library/gg328127(en-us).aspx
http://technet.microsoft.com/de-ch/library/microsoft.xrm.sdk.discovery.idiscoveryservice(en-us).aspx
http://technet.microsoft.com/de-ch/library/microsoft.xrm.sdk.iorganizationservice(en-us).aspx
Die Webservices, sind in der Standard-CRM-Installation enthalten, findet Ihr nach folgendem Schema:
http://%5Bservername%5D:%5Bport%5D/%5BOrganisation%5D/XRMServices/2011/Organization.svc
http://%5Bservername%5D:%5Bport%5D/%5BOrganisation%5D/XRMServices/2011/Discovery.svc
Wie man eine WebReferenz hinzufügt, habe ich in einem meiner letzten Blogs beschrieben.
Bevor wir zum eigentlichen Import-Code kommen, sei erwähnt, dass ich die Late-Binding-Variante verwendet habe. Man kann auch das sog. Early-Binding verwenden, das ist jedoch nicht Scope dieses Blog-Eintrags. Eventuell widme ich dem Thema noch später im Laufe des Projekts. Falls das so ist, werde ich diesen Artikel aktualisieren oder erweitern.
Nachfolgend nun das eigentliche Code-Snippet, welches folgende Aufgaben erledigt:
- Auslesen sämtlicher Firmen aus der Quell-Datenbank (mittels ADO.NET Entity Framework)
- Loopen durch alle Firmen
- CRM-Entitäts-Record erzeugen (Account/Firma)
- Eigenschaften mappen
- Einfacher Dublettencheck
- Einfügen / Aktualisieren
static void Main(string[] args) { xxxEntities context = new xxxEntities(); var firmen = (from p in context.Tbl_Firmen orderby p.Firmenname1 select p); foreach(var firma in firmen) { Guid pk; bool insert = InsertOrUpdate(firma.Firmenname1, out pk); Entity account = new Entity("account"); account["name"] = firma.Firmenname1; account["address1_line1"] = firma.Strasse; account["address1_postalcode"] = firma.PLZ; account["address1_city"] = firma.Ort; account["telephone1"] = firma.Telefon; account["telephone2"] = firma.Telefon1; account["fax"] = firma.Telefax; account["emailaddress1"] = firma.EMail; account["emailaddress2"] = firma.EMail1; //account["industrycode"] = firma.Branche1; account["address1_county"] = firma.Bundesland; account["address1_country"] = firma.Land; //account["revenue"] = firma.Umsatz_Tsd; if (insert) Helper.OrgService.Create(account); else { account["accountid"] = pk; Helper.OrgService.Update(account); } } } private static bool InsertOrUpdate(string accountName, out Guid pk) { pk = new Guid(); var accounts = (from a in Helper.OrgContext.CreateQuery("account") where (string) a["name"] == accountName select a).FirstOrDefault(); if (accounts != null) pk = new Guid(accounts["accountid"].ToString()); return pk == new Guid(); }
Nachfolgend noch der Source meiner kleinen Helper-Klasse, welcher nur zwei Properties zum Arbeiten mit dem Organization-Webservice beinhaltet:
public static class Helper { private static IOrganizationService _orgService; public static IOrganizationService OrgService { get { if(_orgService == null) { ServerConnection serverConnect = new ServerConnection(); ServerConnection.Configuration config = serverConnect.GetServerConfiguration(); OrganizationServiceProxy proxy = new OrganizationServiceProxy(config.OrganizationUri, config.HomeRealmUri, config.Credentials, config.DeviceCredentials); proxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior()); _orgService = (IOrganizationService)proxy; } return _orgService; } } private static OrganizationServiceContext _orgContext; public static OrganizationServiceContext OrgContext { get { if(_orgContext == null) { _orgContext = new OrganizationServiceContext(OrgService); } return _orgContext; } } }
Viel Spaß beim Probieren!