views:

50

answers:

4

I have a class

public class Item : IItem
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual bool IsActive { get; set; }
}
public interface IItem
{
    Guid Id { get; set; }
    string Name { get; set; }
    bool IsActive { get; set; }
}

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.IsActive);
    }
}

In my database I have created five items. Three that have the IsActive flag set to true and two that have it set to false.

When using the Interface it returns all five items:

        var q = from i in session.Linq<IItem>()
                where i.IsActive == true
                select i;

However, when using the concrete class it returns the proper three items:

        var q = from i in session.Linq<Item>()
                where i.IsActive == true
                select i;

EDIT
I have would like to return an Interface, because I have read that I should return non-concrete classes. Please note that in actuality, these Linq queries are in a repository in a different project (in case this becomes a web or WPF app)

A: 

I believe you will need to map IItem instead of the concrete Item class to have this work properly.

DanP
A: 

Things you could try:

  • Instead of

    public class ItemMap : ClassMap<Item>
    

    use

    public class ItemMap : ClassMap<IItem>
    
  • Simply cast the objects that are returned:

    var q = from i in session.Linq<Item>()
            where i.IsActive == true
            select (IItem)i;
    
Timwi
+1  A: 

It looks like a bug in the old contrib Linq provider.

Try with NHibernate 3, it works as expected.

Diego Mijelshon
Thanks, @Diego that worked. It took a bit of a run around though, needed to rebuild the assemblies. http://stackoverflow.com/questions/2349400/how-to-get-fluent-nhibernate-working-with-nhibernate-3-x
Nathan Koop
A: 

I don't think you need to worry about querying against concrete types, that is fine. Just have your repository method return an interface. Make sense?

public IItem GetItem(int id)
{

  var item = from i in session.Linq<Item>()
                where i.IsActive == true
                select i;

  return item;

}

This will let you query work as it should and let all your dependent code work against the interface, which is all you really need the interface for anyway.

Corey Coogan