是否可以在LINQ查询中检查空值,当值为null时,它是否一次执行额外(子)查询?
解释
我在我的数据库中声明了默认按钮,默认描述。用户可以自定义这些按钮,这些设置存储在ButtonLocations
表中。现在,每个按钮都有标准描述,用户可以编辑此描述。当用户编辑描述时,它将存储在我的数据库中的Descriptions
表中。
当我检索所有按钮时,我首先检查按钮是否具有特定描述(在 buttonlocations 中,左连接)。如果不是这样(因此为null),我将检索默认描述。
目前,我获取了所有实体的描述,然后我遍历所有实体以检查值是否为空。这导致对数据库的多次查询。
var temp = (from bl in context.buttonLocations
join b in context.Buttons
on bl.ButtonID equals b.ButtonID into buttons
from button in buttons.DefaultIfEmpty()
join d in context.Descriptions
on new
{
ID = bl.ButtonLocationID,
langID = languageID,
originID = descriptionOriginID
}
equals new
{
ID = d.ValueID,
langID = d.LanguageID,
originID = d.DescriptionOriginID
}
into other
where bl.ButtonGroupID == buttonGroupId
from x in other.DefaultIfEmpty()
select new
{
Button = button,
ButtonLocation = bl,
Description = x
}).ToList();
// Retrieve default descriptions if no specific one is set
foreach (var item in temp)
{
if (item.Description == null)
{
item.Description = context.Descriptions
.FirstOrDefault(x => x.ValueID == item.Button.ButtonID && x.LanguageID == languageID && x.DescriptionOriginID == (short)DescriptionOriginEnum.Button);
}
}
答案 0 :(得分:0)
null coalescing operator应该适合你。像这样:
.....
select new
{
Button = button,
ButtonLocation = bl,
Description ?? context.Descriptions
.FirstOrDefault(
x => x.ValueID == button.ButtonID
&& x.LanguageID == languageID
&& x.DescriptionOriginID == (short)DescriptionOriginEnum.Button)
})
答案 1 :(得分:0)
我认为Colin使用coalesce运算符的答案应该有效,但如果无法使用,可以尝试做一个获得两个选项的子选择,然后按优先顺序排序自定义源,并获取最高记录。 (我在这里假设任何给定的按钮只有一个描述,多个描述不应该导致多个按钮。)
var temp = (from bl in context.buttonLocations
join b in context.Buttons
on bl.ButtonID equals b.ButtonID into buttons
from button in buttons.DefaultIfEmpty()
let description = (
from d in context.Descriptions
where
d.LanguageID == languageID
&& (
(
d.ValueID == bl.ButtonLocationID
&& d.DescriptionOriginID == descriptionOriginID
)
||
(
d.ValueID == b.ButtonID
d.DescriptionOriginID == (short)DescriptionOriginEnum.Button
)
)
// this line puts custom descriptions first
orderby d.DescriptionOriginID == (short)DescriptionOriginEnum.Button
? 1
: 0
select d
)
// this will get a custom description if there was one, otherwise
// the first one will be the default description
.FirstOrDefault()
where bl.ButtonGroupID == buttonGroupId
select new
{
Button = button,
ButtonLocation = bl,
Description = description
})
.ToList();
这显然有点尴尬,可能不是最有效的查询。我会尝试首先将合并运算符移动到let description = d ?? /*subselect*/
行。