列上的LINQ联接AND可为null的变量

本文关键字:可为 null AND 变量 联接 LINQ | 更新日期: 2023-09-27 18:00:33

我正在尝试使用LINQ联接表,方法是匹配联接表中的列等于变量或变量为null的列(此时联接仍然需要发生,只是不在该字段上)。

我的LINQ类似于:

var data = (
    from lt in cxt.CmsPageRow
    join page in cxt.CmsPage on new { lt.CmsPageID, cmsSiteID.Value } equals new { page.CmsPageID, page.CmsSiteID }
    ...

cmsSiteID是一个可以为null的INT.

我无法编译我的代码,因为它抱怨"在调用‘Join’时类型推断失败"

除此之外,我只需要在页面上加入。当CmsSiteID不为null时的CmsSiteID。如果cmsSiteID为null,那么lt.CmsPageID上的联接仍然需要发生。

*编辑*

现在问题有点变了。通过在LINQ中的联接上使用WHERE子句,我可以让它做我想做的事情。

join page in cxt.CmsPage.Where(p=>(cmsSiteID==0||p.CmsSiteID==cmsSiteID)) on lt.CmsPageID equals page.CmsPageID

然而,这仍然进展缓慢。如果我将传递的参数更改为文字,它会立即执行。

慢速

(@p__linq__1 = 0 OR [Extent2].[CmsSiteID] = @p__linq__1)

快速通道

(267 = 0 OR [Extent2].[CmsSiteID] = 267)

有没有办法加快速度?

列上的LINQ联接AND可为null的变量

LINQ中的

join假定有一个内部联接(没有null)。试着把空的东西拉到单独的where子句中。我认为这些思路应该适用于你所描述的内容。

from lt in cxt.CmsPageRow
join page in cxt.CmsPage on lt.CmsPageID == page.CmsPageID
where cmsSiteID == null || 
      (cmsSiteID != null && (page.CmsSiteID == null || page.CmsSiteId == cmsSiteID.Value))
select ...

更新

我没有意识到表演对你来说是个问题。在这种情况下,我建议基于运行时已知的值创建一个不同的查询结构,而不依赖于单独的行:

var rows = 
    from lt in cxt.CmsPageRow
    join page in cxt.CmsPage on lt.CmsPageID == page.CmsPageID
    select new {lt, page};
if (cmsSiteID != null)
{
    rows = rows.Where(r => r.page.CmsSiteID == null || 
                           r.page.CmsSiteId == cmsSiteID.Value));
}
var data = rows.Select(...);

此外,如果您的数据上下文设置正确,您应该能够使用导航属性在一定程度上简化代码。

var rows = ctx.CmsPageRow;
if (cmsSiteID != null)
{
    rows = rows.Where(r => r.CmsPage.Any(p => p.CmsSiteID == null || 
                               p.CmsSiteId == cmsSiteID.Value));
}
var data = rows.Select(...);