当LINQ查询的条件为空时,如何防止多个结果?

时间:2015-09-15 07:18:52

标签: c# linq linq-to-sql

假设有以下两个SQL表。

db.Fruits

ID  Name
F1  Apple
F2  Orange
F3  Melon

db.Attributes

ID  Fruits_ID   AttributeType   AttributeValue
A1  F1          Color           Red
A2  F3          Size            Large
A3  F2          Size            Small
A4  F1          Size            Small
A6  F3          Color           Brown

如何使用LINQ查询以多个可空条件搜索我想要的水果,而不是因为JOIN而将结果相乘?例如,如果condition为空,则以下查询会生成多个结果。

var q = from f in db.Fruits
        join a in db.Attributes
        on f.ID equals a.Fruits_ID
        where string.IsNullOrEmpty(condition) || fa.AttributeValue.Contains(conditon)
        select FruitResult
        {
            // ...
        }

无论如何,我也调查了INTO,但那对我不起作用。

var q = from f in db.Fruits
        join a in db.Attributes
        on f.ID equals a.Fruits_ID
        into FruitsAttributes

        from fa in FruitsAttributes
        where string.IsNullOrEmpty(condition) || fa.AttributeValue.Contains(conditon)
        select FruitResult
        {
            // ...
        }

condition为空或空时,上面仍会返回多个/连接结果。

TL; DR:如何在查询中使用一对多.Contains检查,如果条件为空,则返回个别"未加入&# 34;行?

3 个答案:

答案 0 :(得分:1)

您可以尝试此查询:

var q = from f in db.Fruits
                join a in db.Attributes
                on f.Id equals a.FruitId
                into g
                select new FruitResult
                {
                    Id = f.Id,
                    Name = f.Name,
                    Attribute = condition != null ? g.FirstOrDefault(a => a.AttributeValue.Contains(condition)) : null
                };

您可以轻松地在选择中扩展检索属性值,我不知道您需要什么,所以我保持原样。

答案 1 :(得分:1)

如果condition为空,我猜你是否期望空集,因为它不匹配任何属性?最简单的方法就是单独处理这种情况。

IEnumerable<FruitResult> q;
if (!string.IsNullOrEmpty(condition))
{
    q = from f in db.Fruits
        join a in db.Attributes
        on f.ID equals a.Fruits_ID
        where fa.AttributeValue.Contains(conditon)
        select FruitResult
        {
            // ...
        }
}
else
{
    q = Enumberable.Empty<FruitResult>();
}

答案 2 :(得分:0)

终于到了答案。它实际上非常简单,只需要创建一个过滤器并跳过连接。

var qFilter = from a in db.Attributes
              where a.AttributeValue.Contains(condition)
              select a.Fruits_ID

var q = from f in db.Fruits
        where string.IsNullOrEmpty(condition) || qFilter.Contains(f.ID)
        select FruitResult
        {
            // ...
        }