PMKB–un an

Anul acesta o sa fie diferit. Am hotarit sa ma apuc de o singura aplicatie pe care sa o imbunatatesc cel putin 1 ora pe zi.

Ea se numeste PMKB – de la PoorMan Knowledge Base. Poate fi downloadata de la adresa

http://pmkb.codeplex.com/

Ea consta in ordonarea unei colectii de linkuri in tag-uri. Ginditi-va cind ajungeti la un nou serviciu – si toate informatiile sunt diseminate de colo-colo. Ea va ajuta sa adaugati rapid un link cu un tag si sa le regasiti pe urma.

As vrea sa o fac cu tot ce trebuie – de la unit testing la WPF, trecind prin IE Pinned sites si altele.

E facuta in MVC3 . Ce am reusit sa fac este sa o fac functionala si sa ii adaug posibilitatea de plugin-uri. 

O gasiti la adresa http://pmkb.codeplex.com/ – o puteti downloada rapid si instala la fel( e bazata pe EF Code first –derivat din edmx, ma rog – dar CodeFirst si are ca baza de date  SqlServer Compact )

Data viitoare scriu ce am invatat facind-o – si asa o sa continue intregul an.

La multi ani!

La multi ani si sarbatori fericite!

Si, daca ati intilnit un site / cineva / ceva care v-a facut fericiti, donati ceva.

Pentru mine, a fost Wikipedia

wiki3

Daca aveti posibilitatea , faceti un gest acum.

La multi ani!

ORM sau ADO.NET direct

O intrebare care revine deseori este ce folosim :Un ORM ( L2S, EF, NHibernate, custom code) sau ADO.NET direct( procedura stocata, trimitere de query la BD ) ?

Criteriile pe care le folosesc sunt :

  • timpul de dezvoltare  – timpul pe care il aloc eu, ca dezvoltator, ca sa scriu codul
  • performanta – timpul in care codul meu se executa ca sa faca obtina rezultatul dorit. Inclusiv cit imi ia timpul de incarcare al datelor din BD.

Tinind seama de aceste criterii, pentru mine  exista un raspuns clar : depinde.

Enumar cazurile mele principale :

  1. Utilizez un ORM ca sa ma scape de bataia de cap cu filtering/paging/sorting. Daca ati scrie un query de mina cu asta sau o PS – ar fi destul de greu ( oribil ca timp de dezvoltare)
  2. Sa zicem ca vrem sa modificam toate contractele pentru clientii care au > 4 ani si le dam inca o luna gratis. Daca am face asta cu un ORM ar insemna un cursor( oribil ca performanta) – asa ca mai bine facem un  ADO.NET direct “ update  table …” – cu procedura stocata sau direct ca text
  3. Daca vreau sa fac update la o un singur cimp ( de exemplu, daca vreau in incrementez numarul de download pentru un fisier) este absurd(oribil ca performanta: timp de incarcare) sa incarc row-ul de fisier cu ( id, , nume, cale, numarul de download si alte date) ca sa obtin incrementez doar numarul de download si sa salvez inapoi in BD. Mai bine fac un update rapid cu ADO.NET direct . ( Oh, daca sunt puturos , chiar folosesc ORM)
  4. Daca fac update pe mai multe cimpuri, e absurd ( oribil ca timp de dezvoltare) sa scriu un update pentru toate cimpurile. Mai bine folosesc ORM-ul.

Concluzia: folositi right tool for the right job.

Adaugare: Tudor Turcu , http://tudorturcu.wordpress.com/ adauga ca ADO.NET se mai foloseste la reporting si la optimizari de SP. -vezi comentariu.

PS :Mai stiti si alte cazuri ?

Prezentare RONUA / ITCamp

Prezentarea a fost urmatoarea:

EF41 cu tt

– Vine cu VS2010 SP1 . Mai e bine sa va instalati SqlServerCompact 4.0
– Demo 1 : generare bd (Express / Sql Server Compact), required attribute versus fluent api

Fisiere .tt

– CodeSmith
– Genereaza orice – cu conditia sa ai rabdare
– Demo2: generare a 20 de clase

EF41 cu fisiere tt

– De ce DAL/ORM trebuie sa inceapa de la BD si nu invers.
– Istoric : L2S, EDMX, POCO
– Template-ul de ef4.1 este super simplist
– Modificare template-ului de ef4.1

Resurse fisiere .tt :

Oleg Sych – » T4: Text Template Transformation Toolkit
.Net Head » Replacing ResXFileCodeGenerator with a T4 Template: Customize your resource access code.
T4 Templates: A Quick-Start Guide for ASP.NET MVC Developers – Visual Web Developer Team Blog – Site Home – MSDN Blogs
Oleg Sych – » T4 template for generating SQL view from C# enumeration
Get Visual Studio to run a T4 Template on every build – Stack Overflow
( le gasiti in atasamentul zip)ronua

Rezumat

EF4.1 in sfirsit este xcopy deployment ( .NET 4.0). S-ar putea ca EF4.2 sau 5.0 sa fie ok.

Intrebari

Download fisiere
http://serviciipeweb.ro/iafblog/wp-content/uploads/2011/11/ronua.zip

Update:
Prezentarea lui Andrei Rinea despre WCF Streaming o gasiti aici
http://blog.andrei.rinea.ro/2011/11/26/wcf-streaming-slides-and-code/

Curs ASP.NET MVC

Pentru cei interesati, propun un

Program curs ASP.NET MVC

Orice curs trebuie sa se adapteze studentilor. Acest curs se adreseaza celor care vor sa isi imbunatateasca cunostintele de ASP.NET MVC si nu sunt incepatori. Ca urmare cursul va fi de nivel mediu spre greu. Propun 3 zile de curs, fiecare de cite 7 ore.
Cursul e tinut de mine ( iar daca intrebati cine sunt eu cititi acest blog sau un scurt rezumat aici )

Ziua 1.

Recapitulare definitie MVC – view, model , controller. De ce Model nu este database Model, ci ViewModel
Aplicatie practica de generare de ViewModel combinat din doua clase .
Model Binding in MVC : Model binder default( inclusive Binding-ul unei liste).
Aplicatie practica : Binding-ul unei liste. Crearea unui Binding customizat pentru DateTime.
Routing in MVC : cum se foloseste. Probleme des aparute intre query string si rutarea obisnuita.
Aplicatie practica: Rutarea unui slug http://en.wikipedia.org/wiki/Slug_%28web_publishing%29
Validarea in MVC : Validarea obisnuita. Un-obtrusive . Remote
Aplicatie practica: Validarea obisnuita. Un-obtrusive . Remote

Ziua 2.

Razor si MVC: Areas. Layout. EditorTemplates/DisplayTemplates
Aplicatie practica: EditorTemplate pentru DateTime
Ajax in MVC : Ajax cu Jquery. Regasirea actiunilor / partial view
Aplicatie practica: Jquery si interceptarea erorilor de server / comunicatie
Filtre in MVC 3: IAuthorization, IActionFilter, IResultFilter,IExceptionFilter
Aplicatie practica: IActionFilter pentru logarea timpilor de executie al actiunilor.

Ziua 3:

Securitate MVC: Se face pe actiuni, nu pe fisiere.
Aplicatie practica: Authorize pe toate actiunile, mai putin cea de login.
TDD MVC: testare ViewModel . Testarea actiunilor.Testarea View-urilor( Selenium)
Aplicatie practica : Testare ViewModel, Actiuni, View
Sesiune finala de intrebari si raspunsuri

Cu ce va alegeti:

  1. Veti intelege ce aveti nevoie pentru o aplicatie MVC
  2. Veti putea intelege feat-urile noi din MVC
  3. La ( aproape) orice problema de MVC veti sti un posibil raspuns pe care il veti fi facut la curs.
  4. Veti putea avea o sursa de referinta pentru intrebarile voastre

Puteti downloada oferta de aici
Pentru pret va rog sa ma contactati la ignatandrei@yahoo.com

Ubisoft challenge

Am aflat pe ultima suta de metri despre http://www.ubichallenge.ro/ ( intre timp , ca de obicei la concursurile sponsorizate de MSFT RO, au prelungit termenul – acum data limita este 15 noiembrie 2011).

Am zis ca poate e bine sa vad cit dureaza aplicatia – si, de ce nu, sa ma inregistrez video – poate imi dau seama de problemele mele….

Daca aveti timp d0ua ore si 25 de minute ( sparte pe bucati) gasiti cum am facut aplicatia de ScratchCard aici
: http://www.youtube.com/playlist?list=PLC7B07DEEB2AF4602&feature=viewall Sunt 5 bucati de video – si ar trebui sa fac si un postmortem.

Ce a fost interesant la ea : am aflat cum sa fac JSON interdomenii. Bineinteles ca nu eu am facut asta –ci, ca de obicei, un tool (bazat pe Jquery) : http://code.google.com/p/jquery-jsonp/. Cititi readme.txt de la codul sursa.

Codul sursa e aici :http://serviciipeweb.ro/iafblog/wp-content/uploads/2011/11/ubichallenge.zip

Si , cum am spus, video aicihttp://www.youtube.com/playlist?list=PLC7B07DEEB2AF4602&feature=viewall

Aventuri in lumea fisierelor.tt

La prezentarea trecuta RONUA Andrei Rinea a vorbit despre GEO IP lookup pentru aflarea locatiei vizitatorilor.

Motivat de faptul ca Andrei Rinea este un perfectionist si a facut doua cautari, am incercat sa fac si eu o (asa zisa) imbunatatire.

Mai intii am vrut sa citesc mai usor din csv-urile respective.Sa zicem ca vreau sa citesc asta:

Copyright (c) 2011 MaxMind Inc.  All Rights Reserved.
startIpNum,endIpNum,locId
“16777216”,”16777471″,”17″
“16777472”,”16778239″,”49″

……

Am downloadat FileHelpers si am scris codul:

 [DelimitedRecord(",")]
    public class IPRangeAndrei
    {
        [FieldQuoted()] public long Start;
        [FieldQuoted()] public long End;
        [FieldQuoted()] public int LocID;
    }
    public class FileHelperImporter
    {
        public IEnumerable<GeoLocation> ImportLocations(string csvFilePath, int HeaderLines=2)
        {
            DelimitedFileEngine engine = new DelimitedFileEngine(typeof (GeoLocation));
            engine.Options.IgnoreFirstLines = HeaderLines;            
            return engine.ReadFile(csvFilePath) as GeoLocation[]; 
        }        

        public IEnumerable<IPRangeAndrei> ImportIP(string csvFilePath, int HeaderLines=2)
        {

            DelimitedFileEngine engine = new DelimitedFileEngine(typeof(IPRangeAndrei));
            engine.Options.IgnoreFirstLines = HeaderLines;
            return engine.ReadFile(csvFilePath) as IPRangeAndrei[]; 

        }
    }

Pare un pic mai clar . Din pacate, e si mai incet – 2 secunde fata de 1 secunda la un fisier de 117 MB .

Apoi am vrut sa incar la compile time csv-urile, nu la runtime.
Prima oara am incarcat cele de GeoLiteCity-Location.csv – puteti sa le luati de aici : http://www.maxmind.com/app/geolitecity

Am scris urmatorul fisier .tt

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="C:\Users\andrei\Desktop\g\Module\Module\bin\Release\Module.dll" #>
<#
Module.CsvImporter  importer= new Module.CsvImporter ();
var locations = importer.ImportLocations(@"C:\Users\andrei\Desktop\GeoLiteCity_20111004\GeoLiteCity-Location.csv");
#>
using System.Collections.Generic;
using Module;
namespace AndreiTT
{
	public class Location:Dictionary<string, GeoLocation>  
	{
		
		public string GetFileKey(long Key)
		{
			return "K" + Key;
		}
		public Location():base()
		{
			<#
			foreach(var geo in locations)
			
			{
				#>
				this.Add(GetFileKey(<#=geo.Id#>),new GeoLocation(<#=geo.Id#>, "<#=geo.CountryCode#>", "<#=geo.RegionCode#>", "<#=geo.City#>", "<#=geo.PostalCode#>", <#=geo.Latitude#>f, <#=geo.Longitude#>f));
			<#
			}
#>
		}
	}
}

si a iesit fisierul asta ( de vreo 30 MB)

using System.Collections.Generic;
using Module;
namespace AndreiTT
{
	public class Location:Dictionary<string, GeoLocation>  
	{
		
		public string GetFileKey(long Key)
		{
			return "K" + Key;
		}
		public Location():base(320000)
		{
							this.Add(GetFileKey(1),new GeoLocation(1, "O1", "", "", "", 0f, 0f));
							this.Add(GetFileKey(2),new GeoLocation(2, "AP", "", "", "", 35f, 105f));
							this.Add(GetFileKey(3),new GeoLocation(3, "EU", "", "", "", 47f, 8f));
							this.Add(GetFileKey(4),new GeoLocation(4, "AD", "", "", "", 42.5f, 1.5f));
							this.Add(GetFileKey(5),new GeoLocation(5, "AE", "", "", "", 24f, 54f));

Inspirat de aceasta reusita, am facut acelasi lucru si pentru GeoLiteCity-Blocks.
Singura problema a fost ca a dat un fisier de 194 MB – care , la compilare cu Visual studio a dat:
Source file ‘C:\Users\andrei\Desktop\g\App\AndreiTT\Blocks.cs’ could not be opened (‘Unspecified error ‘) 

OK, atunci l-am compilat cu msbuild – a dat:

MSBUild: CSC : error CS0010: Unexpected fatal error – ‘a’

M-am uitat la
http://msdn.microsoft.com/en-us/library/bb546037%28v=vs.90%29.aspx
Si zice:

Unexpected fatal error — ‘error’.
This error is generated when something completely unexpected occurs to stop compilation.

Asa ca l-am spart pe blocks.tt in 5 bucati, fiecare de 1.000.000 de bucati si a generat fisiere de 30- 55 MB . A generat partial class, asta ca sa le puna pe toate la un loc:
Asa ca msbuild a dat o eroare omeneasca
(CoreCompile target) ->
CSC : error CS0010: Unexpected fatal error — ‘Not enough storage is available to process this command. ‘ [C:\Users\andrei\Desktop\g\App\AndreiTT\AndreiTT.c
sproj]

0 Warning(s)
1 Error(s)

Time Elapsed 00:03:34.15

Ok, daca nu poate sa asambleze mai multe .tt din fisiere diferite, atunci sa le pun in dll-uri diferite . Am facut si asta.
A generat 5 dll-uri, fiecare de cam cit 20 MB.
Le-am referentiat , am scris codul sa caute in fiecare dll si … la rulare OutOfMemoryException.

Andrei Rinea ma prevenise – asa ca i-am dat telefon sa ii spun ca e asa cum zice el. M-a intrebat daca am x64. Asa ca … l-am compilat si pe x64. La rulare mi-a inghitit toti cei 4GB de RAM si a blocat PC-ul.

Asa incit fiti prudenti – compile time nu e intotdeauna mai bun decat runtime !

Daca vreti sa experimentati, gasiti aici un proiect cu care sa va jucati :

http://msprogrammer.serviciipeweb.ro/wp-content/uploads/runcomp.7z