c# – 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是一个可以为空的INT.

我无法编译我的代码,因为它抱怨“在’加入’的调用中类型推断失败了.”

最重要的是,当cmsSiteID不为null时,我只需要在page.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中的join假定内连接(无空).尝试将空的东西拉出到单独的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(...);
点赞