Programming Languages Hacks

Importanti regole per linguaggi di programmazione rilevanti come Java, C, C++, C#…

  • Subscribe

  • Lettori

    I miei lettori abituali

  • Twitter

Archive for August, 2013

Where condition: IEnumerable vs IQueryable

Posted by Ricibald on 8th August 2013

Check this LINQ To Entities query

    IEnumerable<Book> books = ObjectContext.Books.Where(x => x.Id == 23);
    books = books.Where(x => !x.IsActive);

The query is, as expected, defferred: only when iterating we’ll get the value.

But…this is the query it produces (!!!):

SELECT *
FROM [dbo].[Books]
WHERE [Id] = 23

But… wait!! And the IsActive condition? This is the trap…!!

Solving the main trap

The extension method where exists in two forms:

If at compile time whe are using the first extension method we’ll execute query using LINQ To Objects. It’s deferred, but the filter is applied in memory on the entire result set and doesn’t filter in the data source…!!!

To fix it, “just” make sure to always use IQueryable.Where:

    IQueryable<Book> books = ObjectContext.Books.Where(x => x.Id == 23);
    books = books.Where(x => !x.IsActive);

Or… better (another reason to always use var!!):

    var books = ObjectContext.Books.Where(x => x.Id == 23);
    books = books.Where(x => !x.IsActive);

This produces the following correct query:

SELECT * 
FROM [dbo].[Books]
WHERE ([Id] = 23) AND ([IsActive] <> cast(1 as bit))

Solving the dependent trap

Now that we know the rule… take attention to write a similar code or you’ll have the same error:

void Test() 
{
    IQueryable<Book> books = ObjectContext.Books.Where(x => x.Id == 23);
    books = FilterActive(books);
    books.Dump();   // show data
}

IQueryable<Book> FilterActive(IEnumerable<Book> books) 
{
    return books.Where(x => !x.IsActive);
}

In the example you are filtering using IEnumerable.Where and this leads to the same error. You need to take in input IQueryable collection.

However, if you need to use IEnumerable because you’ll want to be indipendent of IQueryable you can write the following and it will work:

void Test() 
{
    var books = ObjectContext.Books.Where(x => x.Id == 23);
    books = FilterActive(books).AsQueryable();
}

IEnumerable<Book> FilterActive(IEnumerable<Book> books) 
{
    return books.AsQueryable().Where(x => !x.IsActive);
}

This is a trap, but not a bug. This strange behavior enable this scenario (thanks to @Enzo): the DAL works internally passing IQueryable objects and returns to the caller only IEnumerable. The Business Layer uses the detached IEnumerable to refine the query in memory. The Presentation Layer execute only if needed the mixed query (because deferred).

Posted in .net | 1 Comment »

Crash Reporting in .NET

Posted by Ricibald on 6th August 2013

In your .NET windows application you can’t catch all exceptions. There are critical exceptions that leaves your application inconsistent: in this case let your app crash.

But wait… and error reports? You have two alternatives:

  • use the native Microsoft solution: Windows Error Reporting (WER). It’s not easy to customize but it’s fully integrated in Win OS (i.e. when your application freezes). Here how to use WER.
  • use an off-the-shelf crash reporting library:

Note: if your application is an ASP.NET application, just use the excellent ELMAH

Posted in .net | No Comments »

Scrum Start: come cominciare??

Posted by Ricibald on 2nd August 2013

Dal sito Scrum Alliance:

Scrum è un framework Agile finalizzato a completare progetti complessi. Nato per i progetti di sviluppo software, si adatta bene anche per qualunque progetto complesso o innovativo. Le possibilità sono infinite. Il framework Scrum è solo apparentemente semplice.

Questi i punti principali:

  • Il product owner (PO) crea una lista del desiderato ordinato per priorità chiamato product backlog
  • Durante lo sprint planning il team sceglie uno spaccato del desiderato dalla cima della lista, lo sprint backlog, e decide come implementare i pezzi scelti
  • Il team deve completare il lavoro entro un lasso di tempo definito: lo sprint (tra 2 e 4 settimane) ma si riunisce ogni giorno per valutare i progressi (daily Scrum)
  • Nel frattempo, lo ScrumMaster (SM) mantiene il team focalizzato sugli obbiettivi
  • Al termine dello sprint il lavoro dovrebbe essere potenzialmente consegnabile: pronto per l’uso da parte del cliente, per una demo verso uno stakeholder, per la messa in commercio
  • Lo sprint termina con una sprint review e una retrospettiva
  • Con l’inizio dello sprint successivo, il team sceglie un nuovo set dalla cima del product backlog e il ciclo ricomincia

Lo Scrum è semplice, l’adozione prevede una serie di pratiche complesse da padroneggiare. Esistono moltissimi libri e presentazioni a riguardo.

Ma come si comincia??

Qualsiasi guida Scrum spiega il processo a regime, ma non dettaglia gli step iniziali necessari per portare a regime questo processo. L’obbiettivo di questo articolo è dettagliare dal punto di vista pratico “cosa fare” prendendo spunto da questo libro:

  1. Il PO seleziona il team che lavorerà nel progetto
  2. il PO apre il portale TFS e crea un nuovo Team Project scegliendo come template “Scrum” e aggiungendo i relativi utenti del team
  3. il PO convoca il team e gli stakeholder principali per un requirement workshop iniziale.
    • Lo SM (o il PO se non presente) cerca di sensibilizzare i partecipanti sull’esigenza di non pretendere di definire da subito tutti i requisiti: si dovrebbe discutere solo di requisiti di alto livello, senza scendere in dettagli né in questioni tecniche. Lo SM (o il PO) deve moderare questo aspetto.
    • Per chiarire ulteriormente, lo SM/PO spiega il concetto di user story come un requisito espresso dal punto di vista dell’utente “Come XXX voglio fare YYY per ottenere ZZZ” senza andare oltre questa semplice frase ed entrare in dettagli
    • La durata della riunione è stabilita in 3 ore, organizzata in una stanza con una grande lavagna bianca e pennarelli colorati. Ogni postazione avrà postit e penne.
    • Dopo un brainstorming si arriverà a chiarire i vari user story
  4. il PO produce nel proprio ufficio un foglio excel alimentando il backlog con le user story individuate
  5. il PO ordina rapidamente il backlog nell’excel basandosi inizialmente sull’importanza ignorando l’effort richiesto
  6. il PO trascrive nel portale i vari backlog dell’excel creando così nuovi Product Backlog Item in TFS. Lascia molti campi vuoti come Effort, Acceptance Criteria, Test Cases.
  7. due giorni dopo il PO convoca una riunione con il team ed eventuali esperti per stabilire il Definition of Done (DoD) in cui si concordano le qualità minime che il codice deve sempre avere per considerare concluso un certo task (testato, installato, copertura codice 80%, …)
  8. dopo aver definito il DoD, il PO ha le informazioni necessarie per stimare il lavoro. Convoca quindi una riunione di poker planning utilizzando carte fisiche con valori ?, 0, 1/2, 1, 2, 3, 5, 8, 13, 20, 40, 100, infinito. Per ogni user story viene quindi stabilito il peso in story point in termini di confronto tra user story fra loro
  9. terminata la riunione il PO aggiorna l’Effort in story point dei vari Product Backlog Item in TFS
  10. prima di convocare lo sprint planning il PO esegue un risk assessment per riordinare i product backlog secondo quello con più alto rischio (non è legato con l’incertezza assoluta dei requisiti). Il risk assessment può essere fatto in diversi modi: un modo semplice è calcolare il rischio min-max come prodotto tra gravità e probabilità min-max (dipende da eventuali fattori di mitigazione). In TFS semplicemente si possono trascinare le varie user story per riordinare
  11. per mantenere in stato coerente il backlog (operazione di grooming) il PO ha bisogno anche del contributo del team. Il PO stima un 10% di tempo necessario per mantenere il backlog
  12. il PO sceglie la durata per uno sprint tra 2–4 settimane. Una durata bassa (2 settimane) consente di avere feedback più brevi sullo stato di avanzamento del rilascio
  13. il PO per stimare le tempistiche ha bisogno di conoscere la velocità del team (quanti story point in uno sprint). Per farlo ha bisogno prima della capacità in ore effettivamente lavorabili per poi stimare la relativa velocità sulle user story da implementare:
    • per calcolare le ore effettivamente lavorabili il PO considera i giorni lavorativi, le ferie o feste programmate, il tempo necessario per incontri e varie riunioni di Sprint Planning, Sprint Review, Retrospective. Dal risultato sul lavorabile il PO deve inoltre dedurre il tempo di grooming e di drag: tempo perso per attività non previste. In genere in un team nuovo e non affiatato avrà un drag del 25%. Le ore effettive lavorabili a persona devono essere riportate nel tab Capacity di TFS.
    • per ottenere la velocità iniziale del team il PO convoca una riunione di Sprint Planning preliminare. Durante la riunione il team decompone la user story in cima al backlog in vari task stimando per ogni task le ore necessarie. Alle ore ottenute sottrae la capacità del team calcolata precedentemente: se avanza tempo allora il team procede ad analizzare la prossima user story e così via. Se la user story in esame è troppo generica (epic user story) questa viene eliminata (nelle ultime versioni si può ulteriormente aggregare) a favore di user story più di dettaglio che a loro volta sono decomposte in task. Se avanza poco tempo conviene non tirare troppo la corda cercando di aggiungere un altro user story, specialmente se il team è nuovo. TFS è in grado anche di calcolare la previsione (forecast) su quanti sprint sono necessari per completare il backlog basandosi su una velocità del team dichiarata.
  14. Il PO aggiunge in TFS user story e relativi task individuati con corrispondenti ore. Le user story che sono “epic” vengono eliminate
  15. Il PO inizia il release planning basandosi sul forecast di TFS e categorizzando le user story in temi per trovare un filone comune al rilascio e così dare funzionalità al cliente interamente testabili. Poiché nel primo sprint ci saranno diversi chores (messa a punto degli strumenti di lavoro) il primo sprint avrà meno funzionalità testabili. Alcuni temi sono rilasciabili in uno sprint, altri temi più corposi saranno rilasciabili in due o più sprint, perciò non tutti i rilasci saranno regolari.
  16. con le informazioni a disposizione il PO può stendere dei rapporti excel di massima con il time plan e il budget di progetto calcolando stipendi, hardware, software.
  17. il progetto può ufficialmente partire e andare a regime!

Posted in .net | No Comments »