RONUA 19 oct. 2011

Din nou Ronua cu :

A aparut ASP.NET MVC 4 Developer preview. De asemenea , EF 4.1 care stie Sql Server Compact ( si exte xcopy deployment).
O sa trecem prin dezvoltarea rapida a unei aplicatii helper in care majoritatea codului va fi facut de template-uri.
Ce veti invata:
1. Noutatile din MVC4 si EF4.1
2. Tehnici de dezvoltare usoara pornind de la o Baza de date .

  • GeoIP Lookupgaseste locatia vizitatorilor tai in timp real , Andrei Rinea, http://blog.andrei.rinea.ro/

Se va descarca baza gratuita de la MaxMind si apoi se va construi de la zero un modul de cautare a detaliilor geografice pe baza adresei IP.

 

Din ce mi-a placut ( in afara de prezentarea mea , bineinteles) este ceea ce am facut la sfirsit : BinarySearch cu un custom IComparer. Mergea mai repede decit ce a facut Andrei Rinea – dar, bineinteles, nu intorcea nimic Winking smile

Poze:

 

 

DSC_0145

DSC_0150

DSC_0160DSC_0135DSC_0182

In postul viitor o sa iau codul lui Andrei si fie o sa il imbunatatesc, fie o sa il stric de tot Winking smile

tutoriale MSDN cu 2 romani si RONUA

Simteam nevoia sa ma laud – si doar voua puteam 😉

Sunt pasionat de MVC de o buna bucata de timp – si tin si un blog in engleza, http://msprogrammer.serviciipeweb.ro/

Cei care concep Asp.NET MVC tocmai au pus o pagina de tutoriale de MVC 3 la adresa :

http://msdn.microsoft.com/en-us/library/gg416514%28VS.98%29.aspx

Acolo ( intre altii) e mentionat un post de al meu, precum si blogul in engleza.

Si poate va intereseaza ca mai este un roman mentionat : Radu Enuca , http://weblogs.asp.net/raduenuca/

Nu uitati de intilnirea RONUAdin 19 octombrie 2011, de la TeamNet

Jucandu-ma cu EF4.1, edmx si sql server compact.

Sumar: In acest blog veti afla despre customizarea codului generat de fisiere .tt pornind de la“Database First” . Veti genera cod care va fi bun pentru accesat SqlServer 2005 si SqlServer Compact – precum si care pare sa fie varianta cistigatoare intre Attribute si codul scris pentru definit relatii in CodeFirst.

Cuprins:

De cind a aparut EF mi-a parut ingrozitor ca nu am optiunea simpla de a face deliver la un soft cu o Baza de date linga ea. Inainte, cu VB6 , aveam Access … dar EF nu stia Access. Varianta cistigatoare parea sa fie NHibernate – dar sunt satul sa scriu fisiere de configurare pornind de la baze de date( faceam asta in VB5 cu un generator …)

Asa ca am stat pe EF pina la versiunea 4.1 – care a venit cu suport automat pentru SqlServerCompact 4.0. Asa ca, daca tot aveam de facut aplicatia de chat ( work in progress pe blogul tehnic in EN, http://msprogrammer.serviciipeweb.ro/category/mvc-messaging-system/ , si pe codeplex ), am zis ca sa incep sa folosesc. Am generat baza de date( vezi aici si aici) si am instalat SqlServerCompact 4.0 si ultimul SP pentru VS 2010.

Am creat un proiect care sa aiba fisierul edmx si am generat codul cu extensia pentru EF4.1 code first( click dreapta pe edmx, add code generation item , selectati ADO.NET DbContext generator)

clip_image002

Ei, si aici a inceput nebunia : codul generat de template-ul de EF4.1 code first era minimal . Super minimal. Ingrozitor de minimal.

Sa va arat:

public partial class smsg_MessageThread

{

public long IDMessageThread { get; set; }

public long IDMessageInitial { get; set; }

public long IDMessageReply { get; set; }

public System.DateTime DateInserted { get; set; }

public virtual smsg_Message smsg_Message { get; set; }

public virtual smsg_Message smsg_Message1 { get; set; }

public virtual smsg_Message_Archive smsg_Message_Archive { get; set; }

public virtual smsg_Message_Archive smsg_Message_Archive1 { get; set; }

} 

Care credeti ca e Primary Key? Da , intr-adevar, IDMessageThread – dar cum recunoaste EF Code First? ( Raspuns : automat – vedeti http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx )

Nu mai pun la socoteala uritenia de smsg_Message si smsg_Message1, corespondente la IDMessageInitial si IDMessageReply – care e cu care ?

Oricum , nu mi-a placut . Asa ca am citit despre atributele Key si ForeignKey – si am inceput sa modific template-ul .tt.

(Cum ? Citind la greu. De exemplu, uitati cum arata in Winmerge diferenta intre fisierul initial si cel modificat:

clip_image004

)

Si am obtinut asta:

public partial class smsg_MessageThread

{

[Key]

public long IDMessageThread { get; set; }

public long IDMessageInitial { get; set; }

public long IDMessageReply { get; set; }

public System.DateTime DateInserted { get; set; }

[ForeignKey("IDMessage")]

public virtual smsg_Message smsg_Message { get; set; }

[ForeignKey("IDMessage")]

public virtual smsg_Message smsg_Message1 { get; set; }

[ForeignKey("IDMessageArchive")]

public virtual smsg_Message_Archive smsg_Message_Archive { get; set; }

[ForeignKey("IDMessageArchive")]

public virtual smsg_Message_Archive smsg_Message_Archive1 { get; set; }

} 

Un pic mai bine ,corect ? Are deja

[Key]

public long IDMessageThread { get; set; } 

Mai are


[ForeignKey("IDMessage")]

public virtual smsg_Message smsg_Message { get; set; } 

Dar cum ii pot specifica cu care tabela face FK ? Si cu ce cimp din cele doua ?

Asa ca am trecut la faza a doua – generarea din Context a relatiilor intre obiecte. Iarasi modificare la greu – dar de data aceasta fisierul .tt care genereaza contextul. Versiunea oficiala protejeaza cit poate ea de bine in stilul MSFT pe programatorii incepatori:

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

throw new UnintentionalCodeFirstException();

} 

Am modificat si , dintr-un fisier de 194 de linii, am ajuns la unul cu 281 de linii ( am scris aproape 100 de linii in generator, nu in cod ..)

Am obtinut aceasta :

modelBuilder.Entity<smsg_MessageThread>().ToTable(prefix + “smsg_MessageThread”);

modelBuilder.Entity<smsg_MessageThread>().HasKey(item => item.IDMessageThread);

modelBuilder.Entity<smsg_MessageThread>()

.HasRequired(item => item.IDMessage_IDMessageInitial)

.WithMany(u => u.IDMessage_IDMessageInitial)

.HasForeignKey(x => x.IDMessageInitial)

.WillCascadeOnDelete(false);

modelBuilder.Entity<smsg_MessageThread>()

.HasRequired(item => item.IDMessage_IDMessageReply)

.WithMany(u => u.IDMessage_IDMessageReply)

.HasForeignKey(x => x.IDMessageReply)

.WillCascadeOnDelete(false);

modelBuilder.Entity<smsg_MessageThread>()

.HasRequired(item => item.IDMessageArchive_IDMessageInitial)

.WithMany(u => u.IDMessageArchive_IDMessageInitial)

.HasForeignKey(x => x.IDMessageInitial)

.WillCascadeOnDelete(false);

modelBuilder.Entity<smsg_MessageThread>()

.HasRequired(item => item.IDMessageArchive_IDMessageReply)

.WithMany(u => u.IDMessageArchive_IDMessageReply)

.HasForeignKey(x => x.IDMessageReply)

.WillCascadeOnDelete(false); 

Sa le luam pe rind:

1.

modelBuilder.Entity<smsg_MessageThread>().ToTable(prefix + “smsg_MessageThread”); 

Imi ofera ocazia de a schimba numele tablei din care sa ia datele –prefix il pot pune intr-un fisier de configurare.

2.

 modelBuilder.Entity<smsg_MessageThread>().HasKey(item => item.IDMessageThread); 

Scrie clar cine e PK ( inca nu scrie ca e identity – va las pe voi sa modificati .tt)

3.


modelBuilder.Entity<smsg_MessageThread>()

.HasRequired(item => item.IDMessage_IDMessageInitial)

.WithMany(u => u.IDMessage_IDMessageInitial)

.HasForeignKey(x => x.IDMessageInitial)

.WillCascadeOnDelete(false); 

Ei, aici e mai lung: zice ca lui IDMessageInitial ii corespunde colectia IDMessage_IDMessageInitial . Si ca trebuie sa existe si ca nu face cascade on delete.

E mai bine , nu-i asa?

Ultima problema la fisierele .tt

De cite ori sunt modificate , genereaza cod si suprascriu fisierul generat. Deci, daca facem modificari in fisierul .cs, atunci nu mai trebuie sa modificam fisierul .tt ( sau sa integram modificarile ) . Oricare din variante e proasta. Solutia : partial methods. Ce ar fi daca as scrie codul generat de catre .tt in alt fisier si l-as apela (daca e nevoie) din functia care creaza modelul ? Cod, va rog:


partial void OnBeginModelCreating(DbModelBuilder modelBuilder, string prefix,ref bool Continue);

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

bool Continue=true;

OnBeginModelCreating(modelBuilder,prefix, ref Continue);

if(!Continue)

return;

modelBuilder.Entity<smsg_MessageThread>().ToTable(prefix + “smsg_MessageThread”);

// si celelalte. 


Sa o luam de la inceput :

partial void OnBeginModelCreating

procedura asta se creaza doar daca exista intr-un alt fisier cu partial class la clasa din care face parte procedura. Daca nu exista, nu se creeaza ! Exemplu:

bool Continue=true;

OnBeginModelCreating(modelBuilder,prefix, ref Continue);

if(!Continue)

return;

devine :

bool Continue=true;

if(!Continue)

return;

( Hint : a disparut linia cu procedura )

Daca exista, voi intoarce Continue la false ( doar e argument ref !) si nu se va mai executa codul de dupa ( adicatelea

modelBuilder.Entity<smsg_MessageThread>().ToTable(prefix + “smsg_MessageThread”);

// si celelalte 

Solutia imi pare frumoasa ….dar nu stiu daca si voua.

Acum cum schimbam baza de date: in fisierul de configurare putem pune pentru SqlServer:

<add name=”MessagingDB” connectionString=”Data Source=(local)\sqlexpress;Initial Catalog=SMsgS1;Persist Security Info=True;User ID=smsg;Password=smsg;MultipleActiveResultSets=True” providerName=”System.Data.SqlClient” />

Sau pentru SqlCompact:

<add name=”MessagingDB” connectionString=”Data Source=|DataDirectory|\msg.sdf” providerName=”System.Data.SqlServerCe.4.0″ />

Si EF o sa fie bucuros sa creeze fisierul sdf pentru noi(cu relatii cu tot..)

Incheiere:

Am vorbit despre EF 4.1, despre generare codului cu fisierele .tt ,partial methods precum si despre faptul ca e mai bine sa va faceti configurarea EF4.1 din ModelBuilder , decit din atribute.

Puteti downloada cele 3 (x 2 , context + model ) fisiere .tt

Versiunea VS

Prima versiune

A doua versiune

si sa va jucati cu un edmx. Nu uitati

1. sa nu le puneti pe toate 3 deodata ( modelul generat o sa fie comun si VS o sa se enerveze)

2. sa schimbati in fisierul .tt numele fisierului edmx cu numele fisierului vostru.

PS: Daca va pasioneaza subiectul, veniti la RONUA pe 19 oct. 2011. O sa dezvolt pe larg….

Sql server si scrierea de mesaje

Daca aveti o procedura in sql server care este mai lunga si contine mai multe operatii aveti doua solutii daca ea da eroare :

1. sa o spargeti in mai multe proceduri si sa le executati pe rind – destul de dificil daca este una mar

2. sa puneti ‘print ‘ la fiecare terminare de executie ca sa vedeti unde se opreste – doar ca print-ul trebuie sa contina ceva diferit de fiecare data.
Asa ca m-am gindit sa fac o procedura ca sa faca acest lucru automat:

Ca utilizare este imediata:

declare @var int -- nu e nevoie de initializare...

exec @var =dbo.fStep @var

-- cod

exec @var =dbo.fStep @var

-- cod

exec @var =dbo.fStep @var

-- cod

Si iata procedura :

create proc dbo.fStep( @counter int)
as
begin
declare @a varchar(100)
if(@counter is null)
set @counter =1

set @a= 'step ' + cast(@counter as varchar) + ' at ' + convert(varchar,getdate(),121)
print getdate()

print @a
return (@counter +1)
end

powershell si tratarea exceptiilor

Powershell cistiga din ce in ce mai multa tractiune. Se foloseste in Exchange, SqlServer , VS2010 ( cu NuGet cu tot…). Vine default cu Windows 7 .

Asa ca am inceput si eu, usor usor, sa il folosesc.

Vreau sa scriu aici despre tratarea exceptiilor in scripturi . Dupa ce am scris codul si merge, pun un try/catch de forma:

TRY {

#cod:

}

catch [exception]
{

$eroare="eroare trimis email:" +$_.Exception.Message #am obtinut eroare
write-Host $eroare
$body = $eroare
$body += " Tip Eroare: " + $_.Exception.GetType().FullName
#obtine informatii despre computerul pe care s-a executat scriptul si despre numele scriptului
$Computer = get-content env:computername
$fullnamePC = $Computer + " " + $MyInvocation.MyCommand.Path
$body += " Anunt dat de :" + $fullnamePC

write-Host $body
#trimite email sau scrie in fisier
send-mailmessage -to "...." -from "..." -subject $eroare -body $body -bcc "............" -smtpserver "............";
}

Acum ca e clar, sa vedem ce puteti face cu el:

1. Are pluginuri(cmdlets ) de sql server si exchange. Default vine cu acces la registry, file system, event viewer si altele.

2.poate rula comenzi pe alte PC-uri

http://msdn.microsoft.com/en-us/library/ee706585%28VS.85%29.aspx

3. Are thread-uri:

start-job:

http://technet.microsoft.com/en-us/library/dd347692.aspx

http://sqlblog.com/blogs/aaron_bertrand/archive/2011/01/29/powershell-start-job-scriptblock-sad-panda-face.aspx

PS : Nu uitati de signing – asta cu securitatea te omoara la inceput – dar ai tendinta sa o uiti:

Calea corecta : http://www.hanselman.com/blog/SigningPowerShellScripts.aspx

Calea usoara : Set-ExecutionPolicy Unrestricted

Calea medie : http://technet.microsoft.com/en-us/library/ee176949.aspx

Pentru cei care nu stiu, iata si o carte free: http://rkeithhill.wordpress.com/2009/03/08/effective-windows-powershell-the-free-ebook/

RONUA BUCURESTI 13 septembrie 2011

Urmatoarea intilnire RONUA BUCURESTI va fi pe 13 septembrie 2011,ora 18:30 , la sediul TeamNet (http://www.teamnet.ro/ ,  integrator/furnizor de sisteme informatice ).
Vor prezenta:

Andrei Rinea, http://blog.andrei.rinea.ro/ :

ReSharper – unealta pentru productivitate in Visual Studio

Nu numai ca va prezenta cum va ajuta ci, mai mult, Andrei a obtinut 2 licente de ReSharper oferite de www.jetbrains.com/

Radu Enuca, http://weblogs.asp.net/raduenuca :

Claims –Based Identity si WIF

Radu si-a propus urmatoarea agenda si sper ca va avea timpul sa o faca pe toata:

1. Introducere in Claims –Based Identity si WIF:

– scurta introducere in claims-based identity, concepte cheie si terminologie

– introducere Windows Identity Foundation

2.   Demo1: Externalizarea autentificarii, integrarea cu IsInRole si autorizare ASP.NET, autorizare folosind claims (aplicatii ASP.NET WebForms simple). Daca este timp si cu WCF

3. Scenarii si Arhitecturi: federation, home realm discovery, integrarea cu mai multi provideri de identitate

4. Demo2: WIF si ASP.NET MVC3:

– custom Security Token Service in MVC3

– integrare WIF si MVC3

5. WIF si Windows Azure ACS (Access Control Service)

– scurta introducere in ACS

– adaugarea unui Indetity Provider Custom

– integrarea cu o aplicatie ASP.NET MVC3

Data:13 septembrie  2011, ora 18 : 30

Locatie: Sediul TeamNet , sala Training Multifunctionala.
Str. Splaiul Independentei, No. 319,  RIVER Place, RIVERVIEW House, etaj 8,Sector 6,
(la parter este o clinica CMU)

Va rog sa va aduceti BI / CI  pentru a intra.

Harta: click aici : http://www.teamnet.ro/stiri/harta01.html

Detalii acces:
Poți ajunge aici cu urmatoarele mijloace de transport in comun: metrou , statia Petrache Poenaru , fosta Semanatoarea.

Multumesc si te astept!
Andrei Ignat

Enervare

Nu reusesc sa ma refac ca sa scriu un tutorial( o sa il scriu …) , dar as vrea sa va propun un thread de la adresa http://forums.asp.net/t/1709879.aspx

Eu sunt de parere ca
1. Cineva cu ani buni de experienta de programare ar trebui sa faca o diferenta intre un cod  de DAL(EFsau orice alt ORM) si unui de GUI ( ASP.NET MVC)
2.Cineva cu ani buni de experienta de programare ar trebui sa fie in stare sa poata sa gindeasca inainte de a scrie”I have also created another class with the DbSet<> properties inheriting from DbContext.”

3. Cineva cu ani buni de experienta de programare se gindeste de doua ori inainte de a scrie : ”  But I’m an Enterprise developer, not a “shade tree” developer who uses “dbo” schemas in the database, assigns users and passwords in connection strings”  .

Nu reusesc sa vad nimic gresit in a utiliza dbo. Nici in a utiliza connection strings in (web|app).config.

Si ma opresc aici, ca incep sa ma enervez. Voi ce credeti?