1. En o/r mapper har ett DAL i sig som den använder sig av. Tanken är att du inte ska beghöva accessa databasen direkt via detta utan ställa frågor mot din domänmodell som o/r mappern översätter till sql som den låter sitt DAL hantera. Vissa o/r mappers exponerar sitt DAL så man kan använda det och passera själva o/r mappningen.
2. Jag tycker också att NHibernate är bra. NPersist som är en del av puzzle framework är också utmärkt.
Då jag inte har tillgång till ASP.NET 3.x så är inte LINQ ett alternativ
Så jag tror inte att entity framework är ett alternativ ;)
Ett exempel på struktur skulle kunna vara:
UI: Validerar input så nära klienten som möjligt, har en referens till BLL, ropar på t.ex BLL.addCustomer och skickar med ett nytt Customer-objekt med massa information i.
BLL: Startar o/r mappern, och låter den spara customer-objektet och kanske nåt annat (vad det nu kan vara, typ logg eller kopplingar till grupper och medlemskap) inom en transaktion.
Entiteter: Du kan göra ett lager med dina Entiteter (affärsobjekt). Detta lager brukar jag tänka mig som ett vertikalt lager som samtliga andra lager kan referera till.
Om du använder dig av NHibernate så gör man xml-filer som hör till varje entitet som beskriver hur de skall lagras i databasen och hur de förhåller sig till andra entiteter.
Det räcker. Hade du inte använt en o/r mapper hade ditt BLL ropat på ditt DAL för att spara information i databasen. Det du hade fått gör själv i så fall var att generera sql och om du vill använda objekt hela vägen från BLL till UI så hade du varit tvungen att översätta från dina objekt till/från datatables/datareaders och sql. O/R mappern sköter även enklare cache:ning nära databasen som du eventuellt hade velat göra själv.
Det är en ständig debatt hur mycket man skall skikta upp sina applikationer. Man kan göra det precis hur avancerat som helst och i min mening tenderar folk att överarbeta strukturen för sakens skull. En bra tumregel är att när man märker att ens kod mest ropar på ett annat lager med samma information som kom in så gör man dubbelarbete. Argumentet för är naturligtvis att man förenklar skalbarheten.
Vad det gäller inloggningsmekanism så föredrar jag de sätt som det finns inbygt stöd för i .NET dvs forms-inloggning. Jag antar att du med sessions-inloggning menar egen koll av sessionen.
Det finns oändligt mycket att skriva i detta ämne och man kan göra det precis hur avancerat eller enkelt man vill. Gör man det för att öva och förstå finns det ju ett värde i att göra det hela vägen.
Vissa föredrar att lägga logik i sina entiteter för att spara sig själva. Personligen tycker jag att det är lite svårt att få det tillräckligt löst sammankopplat då eftersom man helst inte vill att de ska behöva veta någonting om sql och sådant om man vill ha en utbytbar struktur.
Men som sagt: man tenderar att överkomplicera lösningar och det är i min värld ytterst sällan man verkligen kommer att t.ex byta ut databas helt och hållet. Se istället till att du förenklar korrigeringar och omstruktureringar i din applikation. Det är väldigt vanligt att man vill ändra/bygga ut sin logik, min prio är alltid att underlätta detta.
Detta blev en mindre uppsats, hoppas att du blir klokare. Sätt igång med ett litet projekt och återkom med konkreta frågor :)