views:

85

answers:

2

It seems that NHibernate needs to have an id tag specified as part of the mapping. This presents a problem for views as most of the time (in my experience) a view will not have an Id. I have mapped views before in nhibernate, but they way I did it seemed to be be messy to me.

Here is a contrived example of how I am doing it currently.

Mapping

  <class name="ProductView" table="viewProduct" mutable="false" >
    <id name="Id" type="Guid">
      <generator class="guid.comb" />
    </id>
    <property name="Name" />
<!-- more properties -->
  </class>

View SQL

Select NewID() as Id, ProductName as Name, --More columns
From Product  

Class

public class ProductView
{
    public virtual Id {get; set;}
    public virtual Name {get; set;}
}

I don't need an Id for the product or in the case of some views I may not have an id for the view, depending on if I have control over the View

Is there a better way of mapping views to objects in nhibernate?

Edit
Answer So Far

Mapping

  <class name="ProductView" table="viewProduct" mutable="false" >
    <id name="Id" type="Guid">
    <property name="Name" />
    <!-- more properties -->
  </class>

Class

 public class ProductView
    {
        public virtual Name {get; set;}
        //more properties
    }

View SQL
Do I still need NewID()?

Select NewID() as Id, ProductName as Name, --More columns
From Product  
+1  A: 

As far as I know, NHibernate will require either an id or a composite-id definition since it's the mechanism by which it uniquely identifies a given record. If there is no combination of columns that provides a key for each row in the view, I think you are stuck with hacky workarounds.

Ben Hoffstein
I wish that when you mark a class as `mutable=false` that the explicit need for an Id goes away. not sure if that is practical but would make scenarios like this easier to handle, imo.
Nathan Fisher
+1  A: 

You can make it just a little bit cleaner by not mapping the Id to a property and omitting the generator:

<id column="Id" type="guid"/>

That way, you keep the problem in the data layer, without leaking the implementation detail to your domain.

Diego Mijelshon
does that mean that I can remove the NewID() from the TSQL Select as it is only there to satisfy nhibernate's need to an ID
Nathan Fisher
No, that means your class doesn't need an Id property.
Ben Hoffstein
Ben's right. NHibernate does not need the Id to be mapped to a property, but it always needs a way to identify persistent instances.
Diego Mijelshon
thanks Diego, Ben. Ok let see if I understand correctly. I need to include the id tag in the mapping, I dont need an Id property in my class. Do I then need the need the newid() as part of sql or can that be droped as well and nhibernate will assign a guid to it?
Nathan Fisher
You still need the newid(); NHibernate can only assign Ids on save, not make them up on load.
Diego Mijelshon
Thanks Diego, I don't want nhibernate to save if it is a view. I only want it load. and if I have to explicitly include a newID() in the TSQL to get around this then so be it. unless there is another way that I am missing?
Nathan Fisher