【问题标题】:Get Max row (Linq, NHibernate)获取最大行数(Linq,NHibernate)
【发布时间】:2012-04-23 12:01:57
【问题描述】:

遇到了一个问题,我希望上次导入数据以显示失败。我最终求助于 HQL,因为我必须执行两个查询,任何人都可以看到为什么这在 Linq to NHibernate 中不起作用(正确),这是 3.1 中的一个已知错误吗?

我要写的 sql。

select JobImport.* from 
JobImportResult
inner join (
    select Max(JobImportResultId) as JobImportResultId 
    from JobImportResult
    group by JobImportId
)as tbl on tbl.JobImportResultId = JobImportResult.JobImportResultId
inner join JobImport on JobImport.JobImportId = JobImportResult.JobImportId
where ImportFailureReasonId is not null

我最终编写的 HQL。

select jir.JobImport from JobImportResult jir where jir.Id in 
(select max(mjir.Id) from JobImportResult mjir group by mjir.JobImport)
and jir.ImportFailureReason is not null

有效的 Linq(但我认为在 2000 行之后会中断)

var innerQuery = Query<JobImportResult>()
    .GroupBy(jir=>jir.JobImport)
    .Select(jir=>jir.Max(jr=>jr.Id));

var innerQueryListed = innerQuery.ToList();

var resultQuery = Query<JobImportResult>()
    .Where(jir => innerQueryListed.Contains(jir.Id) && jir.ImportFailureReason != null)
    .Select(jir => jir.JobImport);

不起作用的 Linq :(

var innerQuery = Query<JobImportResult>()
.GroupBy(jir=>jir.JobImport)
.Select(jir=>jir.Max(jr=>jr.Id));

var resultQuery = Query<JobImportResult>()
.Where(jir => innerQuery.Contains(jir.Id) && jir.ImportFailureReason != null)
.Select(jir => jir.JobImport);

【问题讨论】:

  • 当你说它在 2000 行后中断,错误是什么?
  • 啊,我不知道,我知道包含的是性能上的恶魔,虽然呵呵:)
  • 确实如此。我更喜欢我加入子查询的 SQL 查询,但据我所知,NH 目前不支持它:(
  • 它确实支持连接,您需要使用连接和分组依据。类似这样:stackoverflow.com/questions/695506/…

标签: c# sql linq nhibernate linq-to-nhibernate


【解决方案1】:

您使用的是 .NET 4 吗?如果是这样,试试这个:

var innerQuery = Query<JobImportResult>()
    .GroupBy(jir=>jir.JobImport)
    .Select(jir=>jir.Max(jr=>jr.Id))
    .ToList();

var resultQuery = Query<JobImportResult>()
    .Where(jir => innerQuery.Any(j => j == jir.Id)
        && jir.ImportFailureReason != null)
    .Select(jir => jir.JobImport)
    .ToList(); //only use this if you want to resolve the query

或 .NET 3.5 将 resultQuery 部分更改为:

var resultQuery = Query<JobImportResult>()
    .Where(jir => innerQuery.Count(j => j == jir.Id) > 0
        && jir.ImportFailureReason != null)
    .Select(jir => jir.JobImport)
    .ToList(); //only use this if you want to resolve the query

【讨论】:

  • 我使用的是 .Net 3.5。并且解决方案有效! .Net 4 解决方案看起来也将具有 2000 个结果限制并执行两个查询。
  • 您能解释一下为什么 innerQuery.Count 有效但我的原始查询无效吗? (这是 NH 更高版本中修复的错误/功能)
  • 很高兴它有效。我认为您的原始查询不起作用,因为您在执行 ToList 之前正在执行 Contains,并且 NHibernate 在执行 Queryable 上的 Contains 时遇到问题。我在 NHibernate 中看到了一些情况,当使用诸如 IsNullOrWhiteSpace 之类的东西时会抛出 NotSupportedException ,最好的办法(直到他们修复它)是首先解决查询(使用 ToList)然后做你不能做的逻辑在原始查询中实现。
  • 关于 .Net 4 解决方案,Any 基本上是 Count,但它要快得多,因为它一旦找到匹配项就会停止,而 count 显然会一直遍历,直到遍历整个列表.
  • 我想要了解的是子查询的使用。如果与 count 结合使用,但不与 contains(转换为 in)或 any(转换为存在)结合使用,它们可以工作,除非子查询是预先执行的(这会导致任何主查询的 2000 输入限制)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
  • 2020-11-17
相关资源
最近更新 更多