---
title: "nhibernate + generic dao"
type: "forum-thread"
url: "https://www.webforum.nu/amne/dotnet/169270-nhibernate-generic-dao"
topic: ".NET"
topic_url: "https://www.webforum.nu/amne/dotnet"
author: "doggelito"
published: "2008-02-22T13:16:33.000Z"
updated: "2008-02-28T23:14:08.000Z"
replies: 27
views: 1246
page: 1
pages: 2
language: "sv-SE"
site: "webForum — webforum.nu"
rights: "Upphovsrätten till varje inlägg tillhör dess författare."
attribution: "Citera som: webForum, https://www.webforum.nu/amne/dotnet/169270-nhibernate-generic-dao"
---

# nhibernate + generic dao

_Sida 1 av 2._

## #1 — doggelito, 2008-02-22T13:16Z

jag skulle behöva plugga på lite om generics i dao sammanhang men får inte fram nån vettig googling.
det jag vill uppnå är att kunna ha 1 dao-interface som innehåller mina dao:s.
allt är sedan mappat genom nhibernate.
sen vill jag kunna skicka in ex. en produktklass in i interfacet för att spara den i databasen.

jag har sett vissa exempel på detta men det är så svårt att förstå när man bara skrollar radvis med kod.

nån som läst nån bra artikel eller så om detta? :D

Permalänk: https://www.webforum.nu/p/169270

## #2 — erka, 2008-02-22T13:33Z

Du vill alltså få fram en typ av ActiveRecord-tänk? Isåfall är ActiveRecord fårn CastleRecord kanske ett alternativ. Annars bör det väll inte vara så svårt att göra ett generiskt dao utan den hårda kopplingen mellan domän och persistent som AR skapar.

```
public interface IGenericDao<T> : IDisposable
{
        /// <summary>
        /// Gets an object by id
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        T GetObjectById(Guid Id);

        /// <summary>
        /// Saves a new object
        /// </summary>
        /// <param name="objectToSave"></param>
        /// <returns></returns>
        T SaveNewObject(T objectToSave);
 }
```

 
 
 

```
  public class NHibernateGenericDao<T> : NHibernateDaoBase, IGenericDao<T>
	{
        /// <summary>
        /// Gets an object by Id
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public T GetObjectById(Guid Id)
        {
            try
            {
                ICriteria criteria = Session.CreateCriteria(typeof(T));
                criteria.Add(Expression.Eq("Id", Id));
                return criteria.UniqueResult<T>();
            }
            catch (Exception)
            {
                throw;
            }
        }
		
		/// <summary>
        /// Saves a new object to the database
        /// </summary>
        /// <param name="objectToSave"></param>
        /// <returns></returns>
        public T SaveNewObject(T objectToSave)
        {

            ITransaction tx = null;
            try
            {
                tx = Session.BeginTransaction();
                Session.Save(objectToSave);
                tx.Commit();
            }
            catch (Exception)
            {
                if (tx != null)
                    tx.Rollback();
                throw;
            }
            return objectToSave;
        }
		
	 }
```

 

Sen får du väll bygga på fecthingstrategies-möjligheter etcetera

Permalänk: https://www.webforum.nu/p/2084394

## #3 — doggelito, 2008-02-27T15:40Z

Tack erka! Det var lite lagomt mycket kod att ta in. :bire
Nu ska jag bara försöka få in lite villkor och sorteringar i detta så blir det riktigt bra! :)

Permalänk: https://www.webforum.nu/p/2085253

## #4 — Nickemannen, 2008-02-27T18:25Z

Jag gillar inte namnet DAO jag tycker det skär sig så jag googlade lite och hittade denna sida.
<http://in.relation.to/Bloggers/RepositoryPatternVsTransparentPersistence;jsessionid=F2A0568575745D9DF058204AE4026803>

Jag gillar Repository, det känns som att man kan säga att NHibernate är det som är DAO i detta fallet och det ni wrappar in det i är en Repository.

Permalänk: https://www.webforum.nu/p/2085281

## #5 — erka, 2008-02-27T20:06Z

Det är ju ett DAO, därav namnet, förstår inte hur du menar att det skär sig? Jag vill inte ha den hårda kopplingen mellan repo och mina domänobjekt, seperation of concerns. Så jag håller med författaren och gillar ett interface / dao approach. 

Jag anropar inte dao direkt utan kommunicerar alltid genom ett service interface. Och på det viset får jag en tydligare ingång för olika delar av min applikation, ett service interface kan göra saker i flera iolika daos. På det viset tydligare, men utan en så hård koppling som repo skulle ge

Permalänk: https://www.webforum.nu/p/2085299

## #6 — Compusa, 2008-02-27T20:49Z

Noterade denna raden:

```
public interface IGenericDao<T> : [B]IDisposable[/B]
```

 

Har själv funderat på att låta mina DAO:s implementera IDisposable. Antar att du har implementationen av "Dispose" i NHibernateDaoBase? Det är i alla fall så som jag tänkt och sedan stänga mitt ISession-objekt etc.

Anledningen till detta är för jag ska skulle vilja kunna använda min DAO i stil med:

```
using (IUserDao userDao = daoFactory.GetUserDAO())
{
    ...
    userDao.MakePersistent(user);
   ...
}
```

Permalänk: https://www.webforum.nu/p/2085306

## #7 — erka, 2008-02-27T21:57Z

Det är rätt uppfattat, fast inte i alla implementationer, beror på vilken sessionfilosofi som används

Permalänk: https://www.webforum.nu/p/2085316

## #8 — doggelito, 2008-02-27T22:27Z

> **erka skrev:**
>
> Det är rätt uppfattat, fast inte i alla implementationer, beror på vilken sessionfilosofi som används

Vilka olika filosofier finns?

Permalänk: https://www.webforum.nu/p/2085319

## #9 — erka, 2008-02-27T23:00Z

Vanligast är väll session per request, men även där har du ju lite olika val, du kan ju implementera det som att den flushar sessionen först när requesten tar slut så att säga, eller att det sker efter varje dao. Så att du antingen bara gör det du går in för att göra via dina daos eller att objekt som råkas uppdateras på andra ställen, kanske i din codebehind (eller vad du nu har) automatiskt sparas ner vid flusch.

Permalänk: https://www.webforum.nu/p/2085321

## #10 — Compusa, 2008-02-27T23:10Z

> **erka skrev:**
>
> Ett service interface kan göra saker i flera iolika daos. På det viset tydligare, men utan en så hård koppling som repo skulle ge

Har du lust att visa ett mindre exempel på hur det kan se ut? Hämtar du dina DAO:s från en IoC-container? Har kollat lite på Castle Windsor men är lite osäker på hur jag ska göra då jag inte riktigt får ihop helheten. Visa gärna i ett flöde (lager för lager). :)

Permalänk: https://www.webforum.nu/p/2085322

## #11 — Gladh, 2008-02-28T07:08Z

> **Compusa skrev:**
>
> Har själv funderat på att låta mina DAO:s implementera IDisposable. Antar att du har implementationen av "Dispose" i NHibernateDaoBase? Det är i alla fall så som jag tänkt och sedan stänga mitt ISession-objekt etc.

Nu använder jag inte NHibernate så jag kan vara ute och cykla, men vad i dina DAO objekt kräver att du implementerar IDisposable. Har det med NHibernate att göra? För annars så ser jag inte någon anledning att implementera IDisposable på "vanliga" DAO objekt. De förstörs ändå själv av GC när de inte används längre

\- M

Permalänk: https://www.webforum.nu/p/2085331

## #12 — spango, 2008-02-28T09:52Z

Antagligen av samma anledning som alla objekt som använder en resurs är disposable, dvs att det är god ton att fimpa resurser när man är klar med dem, och inte vänta tills nästa gång GC:n behagar gå igång? :)

Permalänk: https://www.webforum.nu/p/2085350

## #13 — doggelito, 2008-02-28T11:07Z

Vad är best practice när det gäller fetchmode?
Jag tänkte att man kan ha en property som innehåller en modeklass men då får jag inte med propertyn eftersom ett interface inte kan innehålla medlemmar.
Så, hur stuvar jag om detta?

```
public interface IGenericDao<T> : IDisposable
{
        [B]FetchParam FetchParam;[/B] error!!!
}

public class NHibernateGenericDao<T> : NHibernateDaoBase, IGenericDao<T>
{
        /// <summary>
        /// Setting fetchtype on collections
        /// </summary>
        private FetchParam fetchParam;
        public FetchParam FetchParam
        {
            get { return fetchParam; }
            set { fetchParam = value; }
        }

        public T GetObjectById(object value)
        {
            try
            {
                ICriteria criteria = CurrentSession.CreateCriteria(typeof(T));
                criteria.Add(Expression.IdEq(value));

                if (fetchParam != null)
                    criteria.SetFetchMode(fetchParam.Name, fetchParam.Mode);

                return criteria.UniqueResult<T>();
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                CloseSession();
            }
        }
}

public class FetchParam
{
        private string name;
        private FetchMode mode;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public FetchMode Mode
        {
            get { return mode; }
            set { mode = value; }
        }

        public FetchParam()
        {
        }

        public FetchParam(string name, FetchMode mode)
        {
            this.name = name;
            this.mode = mode;
        }
}
```

Permalänk: https://www.webforum.nu/p/2085362

## #14 — spango, 2008-02-28T11:38Z

Interfaces kan inte innehålla fält, däremot kan de ha properties (eftersom properties bara är sockrade metoder, egentligen).

```
public interface IGenericDao<T> : IDisposable
{
        FetchParam FetchParam { get; set; }
}
```

Permalänk: https://www.webforum.nu/p/2085368

## #15 — doggelito, 2008-02-28T13:05Z

Ja, men titta där, det funkar ju! Tack spango! :bire

Permalänk: https://www.webforum.nu/p/2085398

## #16 — erka, 2008-02-28T13:11Z

FetchMode kan du lika väll specificera på dina mappningsfiler, det du gör i hql eller criteria overridar det dock. Använder du Lazy Load? FetchMode Eager eller Select är bra att använda just pågrund av problemen med N+1.

<http://www.ayende.com/Blog/archive/7627.aspx>

Men var vaksam på att du inte får galet långa sql-frågor. SQL-profiler är bra för att fatta hur NHibernate "tänker"

Permalänk: https://www.webforum.nu/p/2085399

## #17 — Gladh, 2008-02-28T19:29Z

> **spango skrev:**
>
> Antagligen av samma anledning som alla objekt som använder en resurs är disposable,

Är det NHibernate som är resursen i det fallet då som måste disposas. Så i DAO's Dispose-metod så gör man en dispose på Nhibernates objekt?

\- M

Permalänk: https://www.webforum.nu/p/2085454

## #18 — doggelito, 2008-02-28T20:55Z

> **erka skrev:**
>
> FetchMode kan du lika väll specificera på dina mappningsfiler

Mm, jag har default specat i mappningsfilen och nästan alla collections är specad lazy.
Så om jag vill ladda valda collections till ett objekt så behöver jag overrida via SetFetchMode. Propertyn IList\<FetchParam\> FetchParams (ändrat från FetchParam) fixar tricket åt mig och jag kan ladda de collections jag vill! :)

Dock har jag nu stött på ett problem som ni kanske kan förklara!

Jag har NHibernateGenericDao\<T\> i ett eget assambly: BaseDao.
Sen har jag ex. ProductDao i ett annat assambly som ärver ovan.

Om jag sedan kör ex. denna kod i aspx.cb

```
ProductDao pDao = new ProductDao();
Product p = new Product();
p.Name = "foo";
pDao.Save(p);
```

så får jag:
*The type 'BaseDao.NHibernateGenericDao\`1\<T0\>' is defined in an assembly that is not referenced. You must add a reference to assembly 'BaseDao, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'*

Webprojektet har bara en referens till ProductDao.
Hur undviker jag att behöva lägga till en referens från webprojektet till BaseDao?

Permalänk: https://www.webforum.nu/p/2085475

## #19 — Nickemannen, 2008-02-28T21:15Z

Det beror på var du har interface't

Permalänk: https://www.webforum.nu/p/2085478

## #20 — Compusa, 2008-02-28T22:00Z

> **Gladh skrev:**
>
> > **spango skrev:**
> >
> > Antagligen av samma anledning som alla objekt som använder en resurs är disposable,
>
> 
> Är det NHibernate som är resursen i det fallet då som måste disposas. Så i DAO's Dispose-metod så gör man en dispose på Nhibernates objekt?
> 
> \- M

NHibernate-session (databasanslutningen) är resursen. När man är klar med användingen av DAO:n, så stänger/lämnar man tillbaka anslutningen till connection-pool:en. Det var i alla fall min tanke, men det hela.

Permalänk: https://www.webforum.nu/p/2085481

---

Tråden på webben: https://www.webforum.nu/amne/dotnet/169270-nhibernate-generic-dao  
Nästa sida: https://www.webforum.nu/amne/dotnet/169270-nhibernate-generic-dao/page2.md
