Welcome to MSDN Blogs Sign in | Join | Help

Jag fick frågan om jag inte kunde publicera mina Powerpoint-bilder + SQL 2008-exempel när jag körde lanseringsevent i Malmö igår tillsammans med Magnus Mårtensson från Dotway.

Powerpoint-presentationerna har jag tidigare lagt upp här.

Här kommer de SQL-demos som jag visade - först exemplet på den nya MERGE-funktionen (du kan även ladda hem .sql-filerna direkt här). I nedanstående kod finns även ett exempel på hur du kan radera rader som finns i mål-tabellen men inte i käll-tabellen, något som jag inte visade i min demonstration:

 

USE tempdb

go

/*

DROP TABLE Customers;

DROP TABLE QuarterlyUpdate;

*/

--

-- Step 1: Create and Populate Customers table.

--         Note: Population uses row constructors, which are new in SQL Server 2008

--

CREATE TABLE Customers (

  customer_id         INT IDENTITY PRIMARY KEY,

  customer_name VARCHAR(30),

  policy_type         INT CHECK(policy_type > 0 AND policy_type < 4),

  deductable MONEY,

  number_of_claims INT

)

INSERT Customers VALUES

  ('Robert Smith', 1, 1000, 0),

  ('Mary Johnson', 1, 5000, 0),

  ('Fred Paulson', 2, 2000, 1),

  ('Nancy Jones',  2, 1000, 1) 

GO

SELECT * FROM Customers

GO

--

-- Step 2: Create and Populate QuarterlyUpdate table.

--         Note: Population uses row constructors, which are new in SQL Server 2008

--         Note: Not every Customer must appear in the QuarterlyUpdate table.

--

CREATE TABLE QuarterlyUpdate (

   customer_id INT,

   customer_name VARCHAR(30),

   policy_type INT CHECK(policy_type > 0 AND policy_type < 4),

   deductable         MONEY,

   new_claims INT

)

GO

 

INSERT QuarterlyUpdate VALUES

  (1, 'Robert Jones', 1, 1000, 0),

  (2, 'Mary Johnson', 1, 5000, 2),

  (0, 'Katy Fredericks', 2, 2000, 0),   -- New Customer

  (0, 'Phil Fredericks', 2, 2000, 0)   -- New Customer

GO

SELECT * FROM Customers

SELECT * FROM QuarterlyUpdate

GO

--

-- Step 3: MERGE

--         Note: No action is take when row appears in Customer but not QuerterlyUpdate

--         Note: Uses increment operator, new in SQL Server 2008 T-SQL

--

MERGE Customers C

  USING QuarterlyUpdate Q

  ON C.customer_id = Q.customer_id

  WHEN MATCHED THEN

    UPDATE SET C.customer_name = Q.customer_name,

               C.policy_type = Q.policy_type,

               C.deductable = Q.deductable,

               C.number_of_claims += new_claims

  WHEN NOT MATCHED THEN

    INSERT VALUES(customer_name, policy_type, deductable, new_claims)

    OUTPUT $action, INSERTED.customer_id,

           INSERTED.customer_name as [New Name],

           INSERTED.policy_type as [New Policy],

           INSERTED.deductable as [New Deductable],

           INSERTED.number_of_claims as [New Number Of Claims],

           DELETED.customer_name as [Original Name],

           DELETED.policy_type as [Original Policy],

           DELETED.deductable as [Original Deductable],

           DELETED.number_of_claims as [Original Number Of Claims];

GO

DELETE QuarterlyUpdate;

--

-- Step 5: A row for each current customer is required in QuarterlyUpdate

--         If no row is present, customer will  be deleted

--

INSERT QuarterlyUpdate VALUES

  (1, 'Robert Jones', 1, 1000, 0),

  (2, 'Mary Johnson', 1, 5000, 2),

  (3, 'Fred Paulson', 2, 2000, 1),

  (5, 'Katy Fredericks', 2, 2000, 1),  

  (6, 'Phil Fredericks', 2, 2000, 0),

  (0, 'Sam Fielding', 3, 10000, 0) 

GO

--

-- Step 3: MERGE

--         Note: When row appears in Customer but not QuerterlyUpdate, Customer is deleted

--         Note: Uses increment operator, new in SQL Server 2008 T-SQL

--         Note: Uses WHEN SOURCE NOT MATCHED - keyword SOURCE is required

--          and  Uses WHEN TARGET NOT MATCHED - keyword TARGET is optional

--

MERGE Customers C

  USING QuarterlyUpdate Q

  ON C.customer_id = Q.customer_id

  WHEN MATCHED THEN

    UPDATE SET C.customer_name = Q.customer_name,

               C.policy_type = Q.policy_type,

               C.deductable = Q.deductable,

               C.number_of_claims += new_claims

  WHEN SOURCE NOT MATCHED THEN

     DELETE

  WHEN TARGET NOT MATCHED THEN

    INSERT VALUES(customer_name, policy_type, deductable, new_claims)

    OUTPUT $action, INSERTED.customer_id,

           INSERTED.customer_name as [New Name],

           INSERTED.policy_type as [New Policy],

           INSERTED.deductable as [New Deductable],

           INSERTED.number_of_claims as [New Number Of Claims],

           DELETED.customer_name as [Original Name],

           DELETED.policy_type as [Original Policy],

           DELETED.deductable as [Original Deductable],

           DELETED.number_of_claims as [Original Number Of Claims];

GO

Sedan var det den nya möjligheten att skapa en tabell-datatyp (Table-value type) att använda som inparameter till en lagrad procedur eller funktion. Jag hade förberett genom att lägga till en Inventory-tabell i min AdventureWorks-testdatabas och fyllt den med testdata, så jag har lagt till de stegen till mitt demo script:

USE AdventureWorks

-- Clean up

IF EXISTS (SELECT * FROM sys.procedures sp JOIN sys.schemas ss ON sp.schema_id = ss.schema_id WHERE sp.name = N'myProc' AND ss.name = N'dbo')

DROP PROCEDURE [dbo].[myProc]

IF EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N'myTableType' AND ss.name = N'dbo')

DROP TYPE [dbo].[myTableType]

CREATE TABLE Inventory (id INT,

    name NVARCHAR(100), qty INT);

GO

INSERT INTO Inventory VALUES (1, 'Bicycle', 2),

    (2, 'Roller blades', 5), (3, 'Soccer ball', 10);

GO

 

SELECT id, name, qty FROM Inventory

-- Create a user TABLE type

CREATE TYPE myTableType AS TABLE (id INT,

    name NVARCHAR(100), qty INT);

GO

-- Create a stored procedure that accepts a table-variable

-- of type TABLE as a parameter

CREATE PROCEDURE myProc (@tvp myTableType READONLY)

AS

    UPDATE Inventory SET qty += tvp.qty

    FROM Inventory AS i INNER JOIN @tvp AS tvp

        ON i.id = tvp.id

GO

-- Declare & populate variable of the TABLE type

DECLARE @list AS myTableType

INSERT INTO @list VALUES (1, 'Bicycle', 10),

    (2, 'Roller blades', 5), (3, 'Soccer ball', 25);

-- Execute the stored procedure with TVP

EXEC myProc @list;

GO

SELECT id, name, qty FROM Inventory

Igår gjordes en Beta-version av Service Pack 1 för Visual Studio 2008 och .NET 3.5 tillgänglig som bland annat innehåller en mängd förbättringar för WPF i form av bättre prestanda, en DataGrid-kontoll (jippiii!), Ribbon-kontroll samt en WebBrowser-kontroll. Den innehåller också en mängd andra förbättringar för WCF och webbutveckling samt möjligheten att skapa installationspaket med ett slimmat .NET-ramverk anpassad för klient-installationer.

Jag kommer dock att vänta med att lägga på den på min maskin eftersom den inte är kompatibel med Silverlight 2 Beta1 (se Scotts blog nedan för detaljer). Vill du testa SP1 för VS 2008 och .NET 3.5 så gör det i en testmiljö och inte på din produktionsmaskin.

Scott Guthrie och Tim Sneath har massvis med info kring vad som är nytt.

En av nyheterna i Visual Studio Team System 2008 Test Edition är att det går att spela in webb-tester där ASP.NET AJAX används och automatiskt få med de asynkrona anropen som skickas till servern och svaren som returneras.

I VSTS 2005 gick det att manuellt skapa tester där AJAX användes genom att  lyssna på trafiken mellan webbläsaren och servern med något externt verktyg som t.ex. Fiddler och sedan klippa in anrop och svar manuellt i testen. Med VSTS 2008 slipper du det och kan istället spela in hela flödet av anrop och svar direkt från webbläsaren.

AJAXwebbtest

Jag har spelat in en kort screencast där jag skapar en webb-test som gör en validering mot en ASP.NET AJAX-hanterad kontroll:


När du har spelat in webb-tester för dina olika scenarion är det mycket enkelt att skapa en eller flera last-tester som använder dessa. Du lägger helt enkelt till en ny test av typen "Load Test", konfigurerar denna med bl.a. vilket antal samtidiga användare, vilken bandbredd och vilka webbläsare som ska emuleras - sedan kan du enkelt addera valfria webb-tester som ska köras inom din last-test.

Vill du lära dig mer om webb- och last-tester med VSTS 2008 rekommenderas Ed Glas's blog on VSTS load testing.

Robby Ingebretsens trevliga XAML-editor Kaxaml har släppts i en uppdaterad 1.5 Beta-version med stöd för Silverlight.

Den kommer definitivt bli ett nytt favorit-alternativ till VS/Blend för att köra enklare XAML-demos eftersom den har intellisense, färgkodning, automatisk indentering och några bra snippets med exempel-kod.

kaxaml

Ladda hem Kaxaml här - och missa inte heller Robbys mycket intressant blog där han (bland mycket annat) skriver en hel del om Silverlight och WPF-utveckling.

Det finns fortfarande ett begränsat antal platser kvar till 'Defend Your Application – Developer Security Challenge' - en lag-indelad tävling i säkerhet som hålls hos LabCenter i Stockholm den 28 maj.

Moment och tekniker som ingår i tävlingen är bland andra: Cross Site Scripting, SQL Injection, Parameter Tampering och Cross Site Request Forgery. Läs mer och anmäl dig här.

dzcicon_99ba8882-a6a5-4824-bcb1-709d2997a3b1 Deep Zoom Composer är verktyget för att skapa den typen av zoomningsbara Silverlight-bildkollektioner som används på http://memorabilia.hardrock.se .

Nu finns en uppdaterad version av Deep Zoom Composer tillgänglig som innhåller ett antal förbättringar, bl.a. möjlighet att exportera bild-kollektioner direkt till ett Silverlight 2-projekt med musstöd för att dra runt bilder samt zoom med scroll-hjulet.

Nu finns den nya versionen av Expression Studio tillgänglig. Expression Studio 2 är en produktsvit för dig som arbetar med illustration, webbdesign, hantering av mediaresurser samt Silverlight/WPF-baserad gränssnittsdesign och utveckling.

Följande produkter ingår i produktsviten:

  • webIcon Expression Web - ett webbdesignverktyg för dig som vill skapa webbgränssnitt som fullt ut stödjer vedertagna standarder och samtidigt ger dig full kontroll över design-ytan och smidig integration med Visual Studio. Bland nyheterna märks fullt stöd för ASP.NET 3.5 och ASP.NET AJAX, stöd för Silverlight 1.0, import av Photoshop-bilder samt även PHP-stöd (inklusive inbyggd PHP-server för att kunna granska PHP-sidor) .


  • blendIcon Expression Blend - verktyget för interaktionsdesigners, animatörer och integratörer som länkar samman media och grafikresurser med den kod som hanterar den bakomliggande affärslogiken i WPF eller Silverlight 1.0-applikationer. Några av nyheterna är inbyggd Javascript-editor för Silverlight 1.0, split-vy för design/XAML-kod samt stöd för Vertex-animeringar i XAML.


  • designIcon Expression Design - designverktyget för illustratörer och grafiker som vill kunna blanda bilder med vektorgrafik för användning i WPF/Silverlight eller för att kunna exportera designen till något av de många format som Expression Design stödjer (HTML-kompositioner, PSD, PDF, XAML m.fl.)


  • mediaIcon Expression Media - hanterar dina media-resurser genom rika möjligheter till katalogisering och filtrering av dina resurser. Nyheter är bl.a. stöd för delade kataloger för team som arbetar tillsammans mot samma kataloger, stöd för en uppsjö nya format - t.ex. alla XML-baserade Office format - samt Silverlight-renderade webb-gallerier baserade på dina resurser (bilder, media, vektorgrafik).


  • encoderIcon Expression Encoder - ett verktyg för att koda mediafiler (bild eller ljud) för publicering på Internet. Expression Encoder kan även direkt packa in det kodade mediat i en Silverlight-spelare baserad på en vald mall. Du kan lätt skapa egna mallar eller välja att förändra befintliga genom integrationen med Expression Blend. Nyheter i version 2 är bl.a. stöd för enklare editering, ett exponerat API och en objektmodell som gör det möjligt att starta kodning ifrån din egen tjänst eller applikation samt uttnyttjande av flera processorer/kärnor för att spara tid vid kodningen av media.

Läs mer om Expression Studio 2 och ladda hem testversioner här.

Borta på Microsoft Studios har de roat sig med att klä Anders Hejlsberg i platå-skor och filmat honom tillsammans med Scott Guthrie för en mycket cool video-effekt demo skapad med Silverlight 1.0. Det är en filmsnutt där Anders och Scott går tillsammans ner för en korridor till musik med diverse grafik och effekter - men det som gör det så coolt är att effekterna inte är inkodade i filmen utan är realtids-overlays och du själv styr vilka effekter som ska läggas över - allt i perfekt synk med hur de går!

Silverlight1ToTheMAX

Tekniken de har använt bygger på att MediaElementet har 'Markers' som triggas i takt med att filmen spelas upp, faktum är att Chris Klug visade ett liknande tillvägagångssätt under MSDN Live i höstas. Skillnaden här är att de använder kod-baserad uppbyggnad av sina Markers.

Kolla in Silverlight 1.0 to the Max tillsammans med en bra förklarande artikel + källkod, för att se själva applikationen klicka på bannern med Anders och Scott uppe till höger.

Idag annonserades Live Mesh - en ny plattform från Microsoft som möjliggör utnyttjandet av tjänster och API:er i "molnet". Vi diskuterar Live Mesh i senaste avsnittet av MSDN Radio som publicerades idag - vi samtalar också om hur vi på MSDN och Microsoft Sverige bäst kan hjälpa dig som utvecklare, dessutom har Dag König gjort ett reportage med Joakim Sundén som handlar om etik inom mjukvaruutveckling. Lyssna nedan.

Är du intresserad veta mer om Live Mesh (som än så länge alltså inte är publikt tillgänglig) så har Angus Logan gjort en bra sammanställning över länkar till mer information.

Idag kl 12.00 -  13.00 kommer Johan Lindfors att köra första delen i en serie LiveMeeting-seminarier som kommer att handla om Windows Communication Foundation.

 

Är du intresserad av att lära dig WCF-tekniken från grunden så spring ner till ditt favorit-kafé, handla en sallad och bänka dig framför datorn - anmäler dig gör du här.

Igår gjordes en ny förhandsversion av ASP.NET MVC Preview 3 tillgänglig på Codeplex. Detta är alltså inte den officiella 'Preview 3' som kommer att släppas inom ett par veckor utan en interimsversion av källkoden så som den ser ut just nu.

Fredrik Normén har redan uppdaterat sin steg-för-steg guide med de nya ändringarna.

I den här artikeln ska jag visa hur du kan använda Sockets i Silverlight för att 'pusha' ner data till klienten från en server för att dynamiskt uppdatera en graf - men först lite bakgrund kring nätverksstödet i Silverlight 2:

I och med Beta1 så finns det några olika valmöjligheter om du vill låta din Silverlight-applikation kommunicera med olika tjänster, antingen genom anrop mot tjänster i den domän som din applikation härstammar ifrån - eller genom anrop mot andra domäner som tillåter s.k. cross domain calls - d.v.s. anrop över domängränserna.

Jag kommer återkomma i en senare blogartikel hur kan du åstadkomma anrop mellan olika domäner. Grundinställningen är nämligen att denna typ av kommunikation inte är tillåten för att förhindra s.k. Cross Site Scripting-attacker.

Silverligt 2 Beta1 stödjer dels kommunikation med hjälp av klassen System.Net.WebClient för enklare GET-anrop av typen hämta en sträng eller stream för bearbetning samt System.Net.HttpWebRequest och System.Net.HttpWebResponse för tillfällen när du vill göra POST-anrop och kräver mer kontroll över hur Request Headers hanteras. Karen Colby har skrivit en trivsam artikel där hon går igenom skillnaderna mellan dessa klasser - så som de fungerar i Beta1.

I en kommande release av Silverlight 2 kommer du även att kunna göra POST-baserade anrop och manipulera Request Headers med hjälp av WebClient - skillnaden blir att du med HTTPWebRequest kommer kunna välja att starta anrop från en bakgrunds-tråd (istället att starta dem från gränssnitts-tråden).

Om du vill göra anrop mot tjänster som exponerar ett tjänstekontrakt i form av en WSDL-fil, t.ex. ASMX- eller WCF-tjänst kan du enkelt generera en proxy direkt ifrån Visual Studio 2008 genom 'Add Service Reference'. Den enda skillnaden jämfört med "traditionell" .NET-utveckling är att alla tjänsteanrop i Silverlight är asynkrona. Detta gäller alltså oavsett du använder en genererad proxy eller själv gör anropen med WebClient eller HttpWebResponse.

Så oavsett vilken av de ovanstående sätten som du kommunicerar på så gäller alltså att kommunikationen är asynkron, vilket innebär att du får registrera en eventhandler för ett event som sker när svaret kommer tillbaks från tjänsten du anropar. Detta för att inte riskera att blockera gränssnitts-tråden ifall anropet tar lång tid (vilket i värsta fall skulle kunna krascha webbläsaren).

Men som sagt - den här artikeln skulle ju handla om sockets :-)

I Silverlight 2 stöds alltså också Sockets vilket gör det möjligt att skapa en socket-server med hjälp av TcpListener och sedan låta Silverlight ansluta sig mot servern. Servern kan sedan skicka uppdaterad data till klienten i realtid (eller nja, via en asynkron eventhandler på en bakgrundstråd, men i princip så nära realtid som det går att kommunicera till Silverlight).

I ett exempel som jag visade på Developer Summit uppdaterade jag en graf i Silverlight med data som skickades från en enkel Console-applikation:

graf

När jag letade efter en bra demo för att visa socket-stödet hittade jag följande mycket intressanta exempel från Marc Holmes som visar hur man kan skapa en gränssnittslös Silverlight-applikation som uppdaterar HTML med data från en socket-koppling: Marchitecture - Real-time Data in HTML with Silverlight.

Jag utgick från Marcs socket-kod men ville ha en tydligare grafisk illustration av att data skickades till klienten så jag använde den smått fantastiska open source-komponenten 'Silverlight chart' från Visifire som ger dig tillgång till en uppsjö av mycket snygga grafer som du kan använda i din egen applikation.

Tyvärr hittade jag inget sätt att databinda mot enskilda staplar i Visifire-grafen så jag tar helt enkelt bort hela komponenten från min LayoutRoot och lägger dit den med nytt data för varje 'OnReceive'-event som sker. Du kan ladda hem Visual Studio-projektet här.

En detalj som kanske måste klargöras när det gäller koden i exemplet är följande rad i Silverlight-applikationen, i eventhandler för OnReceive:

this.Dispatcher.BeginInvoke((ReceiveCallback)delegate { UpdateChart(stockList); }, null);

Dispatcher används för att få över svaret (det data som skickas) på gränssnitts-tråden så att jag kan uppdatera gränssnittet med det nya graf-datat.

Det finns några begränsningar i Silverlight 2 Beta1 vad gäller socket-kommunikation:

  • Port-spannet som du kan kommunicera via är begränsat till port 4502 - 4532
  • Du kan bara ansluta till en server på den domän som Silverlight-applikationen kommer ifrån (detta kommer ersättas med en möjlighet att göra säkra anrop över domäner i en senare version)

Idag har jag hållit en presentation om att bygga RIA med Silverlight 2 på Developer Summit.

Presentationen hittar du här.

Jag kommer så fort jag får möjlighet posta ett roligt exempel jag visade där en socket-server pushar ner data till en Silverlight-klient och uppdaterar en graf.

Christian Wigren på Valtech tipsade om den här mycket bra sammanställningen över XAML-verktyg (plug-ins till andra verktyg samt stand-alone produkter, både gratis och kommersiella).