onsdag, juni 11, 2008

Lazy Load och Eager Load med LINQ to SQL

Lazy Load

LINQ to SQL implementerar i grunden ett pattern som heter Lazy Load. Lazy Load innebär att man, som i fallet med LINQ to SQL har att göra med en databas, bara hämtar de rader som man behöver när man faktiskt behöver dem. Inom LINQ kallar man det för Deferred Query Execution vilket betyder att man kan definiera en fråga i ett läge men att kopplingen mot databasen sker först när man börjar iterera resultatet.

När man deklarerar en fråga för att t ex hämta alla kunder som finns i en stad som börjar på bokstaven M:

            var customers = from c in db.Customers

                            where c.City.StartsWith("M")

                            select c;


så kommer det att skapas en representation av frågan i form av ett Query Expression Tree. Om man då sätter break point och debuggar kan man se vilken SQL som kommer att exekveras. Men det är först när man använder någon information från resultatet:

            foreach (var customer in customers)

            {

                Console.WriteLine(customer.ContactName);

            }


som raderna faktiskt hämtas. Så frågan ovan genererar en server-round trip som returnerar 13 rader (om man använder sig av Northwinds databas).

Om man sedan går vidare på varje kund och skriver ut dess ordrar enligt följande:

            foreach (var customer in customers)

            {

                Console.WriteLine(customer.ContactName);

                foreach (var order in customer.Orders)

                {

                    Console.WriteLine(" - " + order.OrderDate.ToString());

                }

            }


så kommer man att för varje kund-objekt generera en ny SQL och hämta just den kundens ordrar. Det innebär att iterationen över kundernas ordrar kommer att generera 14 server-round trips.

Det här kan vara väldigt bra i vissa lägen men mindre bra i andra lägen. Tänk att man har ett presenteras en trädvy där alla kund-objekt visas och sedan väljer användaren att bara expandera en av dessa kunder för att visa kundens alla ordrar. Ja då kanske det är bättre att i bara hämta just den kundens ordrar istället för att skicka över alla kunders ordrar.

Eager Load

Men om man nu har en sådan situation där man vet att man vill ladda alla kunder och alla dess ordrar, dvs man vill använda sig av Eager Load istället för Lazy Load, ja då finns det förstås en lösning och det är DataLoadOptions.

För att lyckas med Eager Load i LINQ så skapar man ett objekt av typen DataLoadOptions och anropar en metod som heter LoadWith. I LoadWith anger man vilka objekt man ska ladda samtidigt som det huvudobjekt man hämtar. Detta gör man med hjälp av ett lambdauttryck. DataLoadOptions-objektet lägger man sedan till i DataContext-objektet. Här nedan har jag använt mig av en object initializer för att sätta propertyn samtidigt som jag skapar objektet.

            var dlo = new DataLoadOptions();

            dlo.LoadWith<Customer>(p => p.Orders);

            var db = new NorthwindDataContext() { LoadOptions = dlo };


Den frågan som jag ställde i början av det här inlägget gällde att hämta alla kunder som bor i en stad som börjar på bokstaven M. När man då skapar ett DataLoadOptions-objekt så är det ett objekt av typen Customer som man anger som typ till den generiska metoden LoadWith och det här objektet är det som kallas grundobjektet. I lambdauttrycket anger man sedan vilket typ av objekt som man vill ladda samtidigt som det grundobjekt man planerar att hämta. Detta innebär att man med en server-round trip kommer att hämta kund-objekten samt dessa kunders alla ordrar.

DataLoadOptions-objektet kan man sedan fylla på med flera relaterade objekt av andra typer som man vill ladda samtidigt som huvudobjektet.

            var dlo = new DataLoadOptions();

            dlo.LoadWith<Customer>(p => p.Orders);

            dlo.LoadWith<Order>(o => o.Order_Details);


Lazy Load är ett fantastiskt pattern men det är väldigt viktigt att man känner till vilka implikationer det kan få att använda det. Lazy Load innebär alltid ett mer chatty interface vilket som sagt kan vara bra ibland men helt förödande i andra lägen.

onsdag, maj 14, 2008

reSharper 3.1 med C# 3.0...

Igår installerade jag reSharper 3.1 på min Visual Studio 2008. Bättre intellisense, bättre refactoring-stöd och en allmänt trevligare utvecklingsmiljö var det som lockade. Tyckte också att det skulle bli kul att se vilket extra stöd man fick till de nya features i C# 3.0 så utan att läsa på allt för mycket installerade jag den senaste versionen, 3.1. Hoppade direkt in och skapa en ny console application i mitt favorit direcotry d:\junk\ och började skriva min favorit LINQ-fråga:

var procs = from p in Process.GetProcesses()

          select p;

 

Men istället för p så poppade en skum intellisense upp och ville ha en typ av nått slag... skrev om skrev om och skrev om men jag fick inte till frågan. Började tro att jag hade hamnat i akut LINQ-koma! Men det visade sig så klart att reSharper 3.1 inte har stöd för C# 3.0 utan då måste man vänta till version 4.0.

 

Det alternativ man har är att ladda ner den senaste nightly builden från reSharper 4.0 men det känns lite väl hard core just nu med tanke på att vissa av byggena är taggade som Not Recommended.

 

 

Så, dags för avinstallation. In på add/remove programs och plocka bort den - gick mycket smärtfritt och sedan tillbaka in till Visual Studio igen men...

 

Ingen intellisense!

 

Det visade sig dock att det bara var en checkbox under Tools/Options/Text Editor/C#. Av någon anledning återställer inte avinstallationen av reSharper "Auto list members" - Puh!

 

Men visst är det så att man är lite sugen på att ladda ner senaste bygget och testa 4.0...

fredag, maj 02, 2008

Plugin-pattern på webben

Martin Fowler har i sin bok Patterns of Enterprise Application Architecture beskrivit ett plugin patter som man kan använda för att länka ihop applikationer genom konfiguration istället för vid kompilering. Min tanke var att bygga en webbapplikation, typ en portal, som sedan blir medveten om att andra applikationer existerar bara genom en konfigurering istället för att man måste känna till den vid utveckling. Min vision var att kunna utveckla och uppgradera portalen för sig och sedan utveckla och uppgradera applikationer för sig.

Jag började med att definiera ett interface som varje applikation måste implementera. Det interfacet ska kunna leverera information om applikationen i fråga:

    public interface IApplicationInfo

    {

        string ApplicationName { get; set; }

    }

 

Sedan la jag till en PluginFactory med en statisk metod getPlugin. Den metodens uppgift var att läsa in assemblyt (snyggt ord) från disk och skapa en instans av den klass som implementerar IApplicationInfo och returnera denna...

public static IApplicationInfo getPlugin(string assemblyName)

{

var assembly = Assembly.LoadFrom(assemblyName);

var assemblyTypes = from a in assembly.GetTypes()

                    select a;

 

foreach (var t in assemblyTypes)

{

    var o = Activator.CreateInstance(t);

    if (o is IApplicationInfo)

        return o as IApplicationInfo;

}

return null;

}

 

Först placerade jag min PluginFactory i samma Visual Studio 2008 projekt som Portalen men det gjorde att mina enhetstester mot getPlugin blev otroligt sega att köra eftersom att den måste starta igång webservern först. Det blev dock betydligt bättre när jag flyttade ut den till ett eget class-library. Ett härligt bevis på hur test-driven utveckling gör att man fattar beslut tidigt som gör att ens arkitektur blir mer testbar!

Nästa steg var att lägga till en AppSetting i min web.config för varje applikation som jag vill att portalen ska känna till och använde mig av en LINQ-fråga för att hämta ut dessa:

var applications = from a in ConfigurationManager.AppSettings.AllKeys

                   where a.StartsWith("PortalApplication")

                   select new { AssemblyName = ConfigurationManager.AppSettings[a] };

 

Grymt coolt! Refelction, LINQ, plugin-patterns och allt möjligt coolt men sen då? Vad har jag vunnit med det här jämfört med att bara lägga in den här informationen i web.config eller i en databas. Hur ska jag nu få mina applikationer att agera i portalen som om de var en del av portalen från första början?

Ju mer jag funderar på det hela desto mer ser det ut som att det är Facebook jag vill bygga (fast utan den sociala delen)... För det är ju precis det Facebook är, en portal med viss gemensam funktionalitet och ett antal tjänster som sedan applikationsutvecklare kan nyttja för att bygga egna applikationer som jackas in i portalen. Så hur har Facebook löst interaktionen mellan en applikation och portalen? Kör varje applikation i en IFrame eller? Är det någon som vet??

tisdag, april 22, 2008

Fråga via Messenger på min blog

Det är fantastiskt kul när någon kontaktar mig på Messenger genom min blog. Då känns det verkligen att det finns någon där på andra sidan som läser det man skriver då och då. Idag hände det för andra gången men den här gången var jag på lunch och kunde inte svara :-(

Frågan handlade om hur man estimerar uppgifter i en sprintplanering i Scrum och om man bör dela upp estimaten för en uppgift i implementation respektive i test.

På Sprint Definition Meeting (som man har innan Sprint Planning Meeting) kommer teamet överens med produktägaren vilka product backlog items man ska implementera under den kommande sprinten. Dessa bryter sedan teamet ner till uppgifter under sprintplanneringen och varje uppgift estimeras. Dessa uppgifter ska estimeras utifrån ett sedan tidigare definierat klart-begrepp där det i min värld absolut ingår test!

Så säg att "Klart" för ett specifikt team betyder "Kodat, Verifierat, Granskat, Incheckat", ja då ska estimatet på 5 story points innebära att det är just kodat, verifierat, granskat och incheckat. Om klart-begreppet istället är "Kodat & Incheckat" (vilket det är för många utvecklare) så har man aktivt valt att lägga test utanför sprinten.

Det kan så klart också vara helt okej att lägga test utanför sprinten. Om man tex har en testavdelning och en testprocess som är implementerad och fungerar bra så tycker jag inte att man ska riva den och flytta in testresurserna i teamen. I alla fall inte initialt, utan då tycker jag att man ska anpassa sig till det man har och se till att man ökar kvaliteten på sina leveranser till testavdelningen tex genom testdriven utveckling.

John, hoppas att det här var svar på frågan du ställde på messenger och om inte är det bara att du hör av dig igen!

onsdag, april 16, 2008

Bug vid konvertering till 2008?

Idag fick jag en fråga från en tidigare uppdragskollega om att konvertera en web-applikation jag jobbat med till Visual Studio 2008. Han hade försökt men lyckades inte och fick det härliga och informativa System.Runtime.InteropServices.COMException. Inget i event loggen, ingen info i konverteringsloggen, ingenting... Man tackar!

Det projektet använder sig av EPiServer och Web Application Project (WAP). WAP var ju först en separat download till 2005, ingick sedan i SP1 och är nu en del av VS2008 så jag trodde att felet var där men icke. Felet ligger istället i hur de olika versionerna av Visual Studio hanterar om IIS finns installerat på utvecklarmaskinen eller inte.

Det finns en inställning under project properties där man kan välja om man ska använda den inbyggda web servern eller om man ska använda IIS. I VS2005 kan man välja det senare alternativet även om man inte har IIS installerat men det kan man inte i VS2008 utan får ”The IIS Web Server is not installed on this computer”.

Det trevliga COMException får man om man först skapar ett Web Application Project i 2005’an, sätter att den ska använda IIS utan att ha IIS installerat och sedan öppnar det i 2008’an.

Så lösningen är antingen att se till att IIS är installerat innan konverteringen till 2008 eller så går man in i projektfilen och ändrar True till False.

[Update 2008-04-22]
Buggen är verifierad sedan länge av produktteamet och kommer att rättas i nästa release (SP1).

tisdag, april 15, 2008

.NET 3.5 Enhancements Training Kit

Som jag har skrivit i ett tidigare inlägg på min blog så finns det ett VS2008 & .NET 3.5 Training Kit. Det här paketet har varit källan till en hel del när det gäller de seminarier jag har hållit tillsammans med Addskills om nyheterna i VS2008 och .NET Framework 3.5. Demos, slides och exempelkod har nyttjats.

Nu är det släppt ett liknande training kit för .NET 3.5 Enhancments som berör följande, kommande, tekniker:
- ADO.NET Data Services
- ASP.NET MVC
- ASP.NET Dynamic Data
- ADO.NET Entity Framework
- ASP.NET Ajax History
- ASP.NET Silverlight Controls

Med tanke på vilken källa till kunskap det förra training kittet har varit så kändes det här som en något perfekt att sätta tänderna i! Men... Det saknas en hel del.

"Presentations will be added in a future release of the training kit."
"Demos will be added in a future release of the training kit."
"Screencasts will be added in a future release of the training kit."
"Resources will be added in a future release of the training kit."

Det enda som finns med är ett par Hands-on labbar. Lite besviken blev jag men precis som de skriver så kommer det att komma i kommande releaser av training kitet.

.NET 3.5 Enhancements Training Kit

Dags för beta-cert!

Idag släpptes tre nya cert från Microsoft i det som kallas .NET 3.5 exams:

70-502: Windows Presentation Foundation
70-503: Windows Communication Foundation
70-504: Windows Workflow Foundation

Dom betatestades under början av året så om det var någon som skrev den under beta-tiden så börjar resultaten att trilla ner nu. Det tar alltså ett par månader från det att man skriver tills man får reda på om man klarade eller inte. Under tiden så utvärderas frågor och feedback, frågor stryks och ändras och sedan sätts en nivå som blir den som gäller för att klara beta-certet. Logga in på MCP-siten - där ser man resutlatet snabbast.

Det är också två andra cert som just nu beta-testas:

70-561: Microsoft .NET Framework 3.5, ADO.NET Application Development
70-562: Microsoft .NET Framework 3.5, ASP.NET Application Development

Betaperioden pågår fram till den 4 maj och det är gratis att skriva. Observera att tiden för certet är fyra timmar och att det är betydligt mycket fler frågor än på ett vanligt cert.

När man ska anmäla sig till beta-cert behöver man en kod och certen börjar med nummer 71 istället för 70.

71-561 – beta code = 561B1
71-562 – beta code = 562B1

Själv ska jag skriva den 29 och 30 april.

onsdag, mars 12, 2008

Cert som pensioneras under 2009

Om ett år, 2009, så kommer ett antal Microsoft-cert som leder fram till MCAD, MCSD och MCDBA att pensioneras. Detta innebär dock inte att man kommer att förlora titeln från sitt transcript. Däremot innebär det att man inte längre kommer att kunna använda något av följande cert i sin examensplan:

Exam 70-300: Analyzing Requirements and Defining Microsoft .NET Solution Architectures
Exam 70-301: Managing, Organizing, and Delivering IT Projects by Using Microsoft Solutions Framework 3.0
Exam 70-305: Developing and Implementing Web Applications with Microsoft Visual Basic .NET and Microsoft Visual Studio .NET
Exam 70-306: Developing and Implementing Windows-based Applications with Microsoft Visual Basic .NET and Microsoft Visual Studio .NET
Exam 70-310: Developing XML Web Services and Server Components with Microsoft Visual Basic .NET and the Microsoft .NET Framework
Exam 70-315: Developing and Implementing Web Applications with Microsoft Visual C# .NET and Microsoft Visual Studio .NET
Exam 70-316: Developing and Implementing Windows-based Applications with Microsoft Visual C# .NET and Microsoft Visual Studio .NET
Exam 70-320: Developing XML Web Services and Server Components with Microsoft Visual C# and the Microsoft .NET Framework
Exam 70-330: Implementing Security for Applications with Microsoft Visual Basic .NET
Exam 70-340: Implementing Security for Applications with Microsoft Visual C# .NET
Exam 70-228: Installing, Configuring, and Administering Microsoft SQL Server 2000 Enterprise Edition
Exam 70-229: Designing and Implementing Databases with Microsoft SQL Server 2000 Enterprise Edition

onsdag, mars 05, 2008

IE8

Har just installerat IE8. Den blev som sagt tillgänglig direkt när Scott hade avklarat sitt keynote och installationen gick otroligt smidigt. Kravet på Vista är SP1 vilket jag tror inte finns tillgängligt för svenska Vista ännu.

En riktigt cool grej är att man kan starta IE8 i en simulerad IE7-mode. Som webbutvecklare finns alltid en oro att installera en ny version av en browser eftersom att man oftast utvecklar för den version som redan finns. Nu med IE8 kan man med en knapptryckning och en omstart köra IE8 som om den vore IE7 vilket är grymt bra.

En annan cool grej är det lilla verktyget Developer Tools som hänger med IE8. Det är motsvarande funktionalitet som IE Developer Toolbar dvs att kunna hitta element på siten osv. Den innehåller tre flikar. HTML, CSS och Script. De två första är ganska självförklarande men den tredje... den tredje är riktigt ball när det gäller ajax och javascript utveckling eftersom att man därifrån kan kliva in och debugga alla sidor man går in på. Hela sidans kod visas och man kan sätta breakpoints och debugga där och då!

WebSlices verkar också rätt coolt men det har jag ännu inte kolla på. Det kommer nog i nästa post...

Mix08 keynote

Sitter hemma och kollar på en live sändning från Mix08 i Las Vegas med Scott Guthrie.

Lite av det som pratas om:

  • Hard Rock-cafe har byggt en grymt grymt grymt cool applikation baserad på Silverlight och Depp Zoom. Johan Lindfors visade Deep Zoom på lanseringseventet men på det sätt Hard Rock har använt det är helt otroligt. Siten finns på http://memorabilia.hardrock.com/ och handlar om all memorabilia de har. Missa den inte!
  • Beta 1 av IE8 kommer att finnas tillgänglig för nerladdning direkt efter keynote. Här är länken:
    http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/Install.htm
  • En ny version av Expression Blend kommer att göras tillgänglig. Den heter 2.5 March Preview och kommer att ytterligare förbättra hur man jobbar med WPF, Silverlight 1.0 och Silverlight 2. http://silverlight.net/default.aspx
  • Silverlight on mobile är på god väg. En demo av en social-nätverks-app på Windows Mobile 6 på en HTC Touch var rätt cool. Det intressanta är att man kan nu utveckla en silverlight app i Visual Studio och Blend och sedan publicera den på mobil utan att ändra ett smack. Lite kul att Scott Gu också levererar "nyheten" att man också kommer att kunna köra Silverlight på Nokia-telefoner som kör Symbian OS. Den här nyheten tipsade dock min kollega Pär Gradin mig om redan i förmiddags på vårt uppdrag in the hood...
  • Visual Studio 2008 Tools for Silverlight Beta 1 finns tillgängligt för nerladdning. http://www.microsoft.com/downloads/details.aspx?FamilyId=E0BAE58E-9C0B-4090-A1DB-F134D9F095FD&displaylang=en

Jag kan varmt rekomendera att se hela keynoten som kommer att finnas tillgänglig på visitmix.com om 24 timmar.

Det coolaste är nog ändå att de spelade Johnny Cash när gästerna skulle komma in på scen! The man in black rules!