【问题标题】:Linq to NHibernate returns different results than HQL?Linq to NHibernate 返回的结果与 HQL 不同?
【发布时间】:2010-03-03 22:18:05
【问题描述】:

我有这个基本的实体设置:

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;}
}

映射:

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);
    }
}

那么为什么当我执行这两个查询时会得到不同的结果呢?

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

我得到 3 个结果,2 个 Instrument.Id = 1 和 1 个 Instrument.Id = 4 vs:

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

这只会得到 Instrument.Id = 1 的 2 个结果。

有人能解释一下 Linq 查询中 Id = 4 的来源吗,或者 NHibernate.Linq 还不是很稳定吗? 谢谢!

【问题讨论】:

  • 您是否尝试过查看 NHibernate 日志的输出?您可以将其配置为输出 SQL。 hibernate.org/364.html。 SQL 可能会为您提供有关映射错误方式的线索。
  • 只是出于好奇,ID = 4 的那个是数据库返回的结果中的最后一个(或者可能是第一个)?这可能只是 NH​​ibernate.Linq 使用的枚举器中的一个错误。
  • 是的,它是最后一个添加到存储库的。经过更多测试,如果我使用 Left Join name.Instrument as inst 进行 HQL 查询,我会得到相同的结果

标签: c# linq nhibernate fluent-nhibernate hql


【解决方案1】:

这听起来像是您使用的 linq 提供程序中的一个错误。您使用的 linq 提供程序来自 NHibernate.Contrib。此提供程序基于标准 api。此 api 可能生成与 hql 不同的 sql。这两个查询创建的sql是什么?

NHibernate 主干中是一个基于 hql 的新 linq 提供程序。此 linq 提供程序将生成与 hql 相同的 sql。在我目前正在处理的应用程序中,我从旧的提供程序转移到了新的提供程序。它似乎比旧的功能更多,但仍未完成。

【讨论】:

  • 我正在使用 NHibernate.Linq v 1.1.0.1001 我没有看到更新的东西 - 还是它仍然是测试版?
  • 哦树干...所以我必须从源代码编译?
  • @cjazz108:您可以从 Hornget 获取树干的二进制文件:hornget.net/packages/orm/nhibernate/nhibernate-trunk
  • 不确定我是否可以四处走动并开始使用躯干进行开发 - 这是我公司的产品。我看到它正在从名称到仪器进行左外连接。有什么办法可以把它变成内部连接?
  • 我不知道如何使用该 linq 提供程序。也许您可以复制一些在某些测试代码中复制错误的代码并将其提交给错误跟踪?我在我公司的产品中使用主干。当您拥有 NHibernate 的所有用法的测试代码时,它必须保存才能移动。我必须在大约 2% 的测试中修复代码。这些测试在第一次运行后失败了。
【解决方案2】:

我在 Sqllite 提供程序(我用于测试)上启用了 ShowSql,并发现它正在为每个选择创建可比较的代码。

由于某种原因,仅 Linq 提供程序(具有 2.0 和 3.0 语法都保留了存储库中的最后一项,这不是 sql 查询的一部分。我通过 sqlite3.exe 和两者之间的输出重新创建了 SQL是一样的。哦,它只发生在 Id 字段上。当我引用不同的字段 (guid) 并将其用于 where 子句 = 结果在 Linq 和 HQL 之间是准确的!

所以答案是我不应该相信它,它是一个错误。感谢您提供的所有帮助 - 如果有机会,我会尝试新的提供商,但现在无法使用我们产品的测试版。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多