views:

236

answers:

2

I have this basic entity setup:

public class Instrument
{
    public virtual int Id { get; set; }
    public virtual Guid? InstrumentGuid { get; set; }
    public virtual string FIPSCode { get; set; }
    public virtual IList Names {get; set;}
}

public class Name
{
    public virtual int Id {get; set;}
    public virtual string Name {get; set;}
    public virtual Instrument Instrument {get; set;}
}

Mappings:

public class InstrumentMap: ClassMap<Instrument>
{
    public InstrumentMap()
    {
        Id(x => x.Id);
        Map(x => x.InstrumentGuid).Not.Nullable();
        Map(x => x.FIPSCode).Not.Nullable();
        HasMany(x => x.Names).Casecade.All;
    }
}

public class NameMap : ClassMap<Name>
{
    public NameMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        References(x => x.Instrument);
    }
}

So why is it that when I do these two queries do I get different results?

var namelist = from name in Session.Linq()
    where name.Instrument.Id == 1
    select name;

I get 3 results, 2 where Instrument.Id = 1 and 1 where Instrument.Id = 4 vs:

var querystr = "select name From Name as name where name.Instrument.Id = 1";
var hqlresult = Session.CreateQuery(querystr).List();

This gets only the 2 results where Instrument.Id = 1.

Could someone explain where the Id = 4 is coming from in the Linq query, or is NHibernate.Linq not quite stable yet? Thanks!

A: 

This sounds like a bug in the linq provider you use. The linq provider you use comes from NHibernate.Contrib. This provider is based on the criteria api. This api might generate different sql than hql. What is the sql created by both of the queries?

In the NHibernate trunk is a new linq provider based on hql. This linq provider will generate the same sql as hql. I moved from the old to the new provider in an application I currently work on. It seams to have more functionality than the old one, but it is still unfinished.

Paco
I'm using the NHibernate.Linq v 1.1.0.1001 I haven't seen something newer - or is it still beta?
cjazz108
Oh trunk... so I'd have to compile from source?
cjazz108
@cjazz108: You can get binaries for the trunk from Hornget: http://www.hornget.net/packages/orm/nhibernate/nhibernate-trunk
Michael Maddox
Not sure I can go out on a limb and start developing with trunk yet - this is for my company's product. I see that it's doing a left outer join from Name to Instrument. Any way to turn that into an inner join?
cjazz108
I don't know how to with that linq provider. Maybe you can copy some code that replicates the bug in some test code and submit that to the bug tracking? I use the trunk in my company's product. It must be save to move, when you have testcode for all usages of NHibernate. I had to fix the code in about 2 percent of my tests. Those test failed after the first run.
Paco
A: 

Well I enabled ShowSql on the Sqllite provider (That I'm using for testing), and found that it is creating comperable code for each select.

For some reason, the Linq provider only (both with 2.0 and 3.0 syntax leaves the last item in the repository, that is not a part of the sql query. I recreated the SQL through sqlite3.exe and the output between the two was the same. Oh and it only happens for the Id fields. When I referenced a different field (guid) and used that for the where clause = the results were accurate between Linq and HQL!

So the answer is it's not supposed to I believe, and is a bug. Thanks for all the help - and when I get a chance I will try the new provider, just can't right now on the beta version of our product.

cjazz108