AX + LINQ + WPF

Všechny technologie zmíněné v nadpisu – Dynamics AX, LINQ (Language Integrated Query) a WPF (Windows Presentation Foundation) – jsou dost rozsáhlé a míchat je dohromady může znít divně. Ale já chci ukázat, jak je lze využít ke zjednodušení složitých věcí.

Vytvoříme jednoduchou WPF aplikaci, která bude zobrazovat data z Dynamics AX. LINQ to AX, což je nová schopnost Dynamics AX R2, bude sloužit jako most mezi AX a WPF aplikací. O LINQ to AX můžete najít více informací v článku Code Example: LINQ to AX from C# na MSDN, ale můžete mít problém okamžitě vidět, jak užitečná celá ta věc je. Já se pokusím být názornější, ale pro detaily se budete muset podívat na MSDN.

Výsledkem bude aplikace jako na obrázku níže. Čte prodejní objednávky z Dynamics AX, filtruje je a zobrazuje v gridu. Obsah můžete scrollovat, můžete vybírat záznamy a řadit je podle nějakého sloupce. Není to mnoho funkcionality, ale na ukázku to bohatě stačí.

Musím vás předem varovat, že následující přístup není – překvapivě – Microsoftem podporován a proto nefunguje úplně ideálně, ale věřím, že se to časem změní.

Budete potřebovat

  • Dynamics AX 2012 R2
  • Visual Studio 2010

Příprava projektu

  1. Vytvořte ve Visual Studiu nový projekt – použijte jazyk C# a šablonu WPF Application.
  2. Otevřete vlastnosti projektu a změňte cílový framework (target framework) na .NET Framework 4
  3. Otevřete soubor app.config a změňte otevírací tag elementu startup na <startup useLegacyV2RuntimeActivationPolicy=”true”>.
  4. Přidejte reference na sestavení obsahující LINQ to AX = přidejte reference na všechny (tři) soubory začínající na Microsoft.Dynamics.AX.Framework.Linq.Data z adresáře bin klienta AX (např.  C:\Program Files (x86)\Microsoft Dynamics AX\6.0\Client\Bin\).

Proxy třídy

  1. Přidejte projekt to AOT (klikněte pravým myšítkem na projektu a vyberte Add {jméno projektu} to AOT).

Přidání WPF projektu do AOT má jeden nepříjemný vedlejší efekt – projekt už nemůže být spuštěn a debugován ve Visual Studiu. V tuto chvíli se tím nezabývejte; vrátim k tomuto tématu později.

  1. Otevřete Application Explorer a přetáhněte tabulku SalesTable do projektu. V tuto chvíli by měl projekt vypadat takto:

Kód

  1. Otevřete MainWindow.xaml a přidejte do gridu následující kód:
    <ScrollViewer>
        <DataGrid x:Name="grid" AutoGenerateColumns="True" />
    </ScrollViewer>

    ScrollViewer zajišťuje zobrazení scrollbarů.
    DataGrid bude zobrazovat data z AX a sloupce vygeneruje automaticky. Nepoužíváme zde žádný binding, protože data nastavíme v C# kódu (proto tam je atribut x:Name).

  2. Vyberte v XAML element Window a otevřete jeho události (v panelu Properties). Dvojklikněte na událost Loaded – to vygeneruje a otevře metodu reagující na událost.
    Jen pro úplnost – takhle nějak by měl vypadat výsledný XAML kód:

    <Window x:Class="SalesOrders.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Sales Orders" Height="350" Width="525" Loaded="Window_Loaded">
        <Grid>
            <ScrollViewer>
                <DataGrid x:Name="grid" AutoGenerateColumns="True" />
            </ScrollViewer>
        </Grid>
    </Window>
  3. Jděte do C# kódu (MainWindow.xaml.cs) a nejdříve ze všeho přidejte na začátek souboru tyto příkazy using:
    using Microsoft.Dynamics.AX.ManagedInterop;
    using Microsoft.Dynamics.AX.Framework.Linq.Data;
  4. Jděte do event handleru (Window_Loaded) a vložte kód pro načtení dat z AX:
    Session axSession = new Session();
    axSession.Logon(null, null, null, null);
     
    QueryProvider provider = new AXQueryProvider(null);
    var salesTables = new QueryCollection&lt;SalesTable&gt;(provider);
     
    var orders = from st in salesTables
                 where st.SalesStatus != SalesStatus.Invoiced
                 select new { st.SalesId, st.SalesName, st.SalesStatus };
     
    grid.ItemsSource = orders.Take(100);

    Objekt Session zajišťuje připojení do AX.
    QueryProvider zpracovává LINQ dotazy.
    QueryCollection obaluje SalesTable proxy, aby mohla být použita v LINQ.
    Pak vytváříme jednoduchý LINQ dotaz – bereme nevyfakturované prodejní objednávky a vybíráme tři pole.
    Poslední příkaz načítá prvních 100 objednávek a přiřazuje je do gridu. Ano, je to takhle jednoduché.

Spuštění

Nyní zkompilujte řešení a aplikace je připravena. Naneštěstí nemůže být spuštěna přímo z Visual Studia, takže otevřete adresář projektu (můžete kliknut pravým myšítkem na projektu a zvolit Open Folder in Windows Explorer) a jděte do bin/Debug. V něm spusťte .exe soubor (v mém případě SalesOrders.exe). Snad všechno funguje!

Spuštění ve Visual Studiu

Je zřejmé, že je efektivnější spouštět aplikace přímo ve Visual Studiu. Nevím, co je za problém s šablonou projektu WPF Application – Microsoft mi řekl, že to není podporováno, ale doufám, že si to rozmyslí.

Stále je možné vytvořit aplikaci ukázanou výše a spouštět ji ve Visual Studio, jen to vyžaduje více kroků (a má to své vlastní slabiny). Myšlenka je založená na tom, že ačkoli WPF aplikace nemohou být spouštěny ve Visual Studio po přidání do AOT, konzolové aplikace mohou. Mohli bysme se pokusit najít prvotní příčinu, ale v tuto chvíli zkrátka vytvoříme WPF aplikaci v projektu Console Application.

  1. Vytvořte projekt Console Application.
  2. Běžte do vlastností pojektu a změňte:
    1. Target framework na .NET Framework 4
    2. Output type na Windows Application
  3. Upravte app.config jak je popsáno výše.
  4. Přidejte reference na:
    1. Sestavení pro LINQ to AX (popsáno výše)
    2. WindowsBase
    3. PresentationCore
    4. PresentationFramework
    5. System.Xaml
  5. Přidejte projekt do AOT
  6. Přetáhněte SalesTable z Application Exploreru do projektu
  7. Zkopírujte MainWindow.xaml a App.xaml z WPF aplikace, kterou jsme před chvílí vytvořili. Nastavte Build Action na:
    1. ApplicationDefinition pro App.xaml
    2. Page pro MainWindow.xaml
  8. Upravte jmenný prostor tříd MainWindow a App v XAML i v C# (je-li to nutné)
  9. Sestavte řešení

Nyní můžete aplikaci spouštět a debugovat ve Visual Studio jako obvykle. Tyto dodatečné kroky zaberou pár minut, ale vrátí se vám velmi rychle, pokud budete potřebovat něco ladit.

Závěr

Aplikace, kterou jsem ukázal, je triviální – vytvoření skutečné aplikace by vyžadovalo více práce. Ale to je tak vždy s ukázkovými příklady. To podstatné je uvědomit si, kolik námahy by stálo vytvoření i takto jednoduchého programu se staršími technologiemi. Nyní je to rychlé, snadné a typově bezpečné. A očividně byste mohli snadno použít komplikovanější LINQ dotazy, bohatší uživatelské rozhraní ve WPF a tak dále.

Jako vždy, není zcela bez komplikací. Problém s WPF Application projekty je jeden z příkladů. Také jsem objevil nějaké podezřelé chování některých LINQ dotazů (musím udělat více testů, než to nahlásím Microsoftu). Ale tohle vše je snad jen dočasné. Pořád je úžasné, jak stále dostáváme více a snadnějších možností k integraci AX s jinými aplikacemi a využívání existujících nástrojů a frameworků.

Pokud neznáte LINQ, vřele doporučuji se na něj podívat. Je to krásná technologie a budete ji moci využít pro práci se spoustou jiných věcí v .NETu (např. s objekty, daty v databázích nebo XML soubory).