Linq - 条件包含()

时间:2016-06-30 10:10:42

标签: c# sql .net linq contains

我有以下方法按照参数中指定的条件过滤商店:

public int[] GetShopIds(IEnumerable<Guid> OrderCreaatorIds, IEnumerable<Guid> OrderItemCategoryIds, int StatusId)
    {
        var query = from s in _db.Shops
                    join o in _db.Orders on s.Id equals o.ShopId
                    join oi in _db.OrderItems on o.Id equals oi.OrderId
                    where
                    OrderCreaatorIds.Contains(o.CreatorId)
                    && OrderItemCategoryIds.Contains(oi.CategoryId)
                    && (int)o.StatusId == StatusId
                    select s.Id;

        return query.ToArray();
    }

事情是:OrderCreaatorIdsOrderItemCategoryIds可以是nullStatusId可以是0。在那种情况下,我不希望有那些条款,例如如果OrderCreaatorIdsnull,则查询应按以下方式运行:

public int[] GetShopIds(IEnumerable<Guid> OrderCreaatorIds, IEnumerable<Guid> OrderItemCategoryIds, int StatusId)
    {
        var query = from s in _db.Shops
                    join o in _db.Orders on s.Id equals o.ShopId
                    join oi in _db.OrderItems on o.Id equals oi.OrderId
                    where
                    OrderItemCategoryIds.Contains(oi.CategoryId)
                    && (int)o.StatusId == StatusId
                    select s.Id;

        return query.ToArray();
    }

不幸的是where OrderCreaatorIds != null && OrderCreaatorIds.Contains(o.CreatorId)无效。

3 个答案:

答案 0 :(得分:1)

尝试以下内容:

var query = from s in _db.Shops
    join o in _db.Orders on s.Id equals o.ShopId
    join oi in _db.OrderItems on o.Id equals oi.OrderId
    where
    (OrderCreaatorIds==null || OrderCreaatorIds.Contains(o.CreatorId))
    && 
    (OrderItemCategoryIds==null || OrderItemCategoryIds.Contains(oi.CategoryId))
    &&
    (StatusId==0 || (int)o.StatusId == StatusId)
    select s.Id;

正如您可以看到where子句的每个部分,我已经将它从简单谓词更改为或检查两个谓词。所以现在你有三个像A || B那样形成的东西。由于方法或逻辑有效,如果A为真,则B将被忽略。因此,如果OrderItemCategoryIdsnull,则不会执行OrderItemCategoryIds.Contains检查。

答案 1 :(得分:1)

public int[] GetShopIds(IEnumerable<Guid> OrderCreaatorIds, IEnumerable<Guid> OrderItemCategoryIds, int StatusId)
{
    var query = from s in _db.Shops
        join o in _db.Orders on s.Id equals o.ShopId
        join oi in _db.OrderItems on o.Id equals oi.OrderId
        select new { s = s, o = o, oi = oi };

    if (null != OrderCreaatorIds)
        query = query.Where(x_ => OrderCreaatorIds.Contains(x_.o.CreatorId));

    if (null != OrderItemCategoryIds)
        query = query.Where(x_ => OrderItemCategoryIds.Contains(x_.oi.CategoryId));

    if (0 < StatusId)
        query = query.Where(x_ => (int)x_.o.StatusId == StatusId);

    return query.select(x_ => x_.s.Id).ToArray();
}

也许您必须向IQueryable添加一些演员&lt;&gt;使其可编辑。我没有在编译器中检查它。

答案 2 :(得分:1)

您可以在查询外的变量中准备查询的动态部分,然后像这样使用里面的变量:

public int[] GetShopIds(IEnumerable<Guid> OrderCreaatorIds, IEnumerable<Guid> OrderItemCategoryIds, int StatusId)
{
    var orders = _db.Orders.AsQueryable();
    if (StatusId != 0)
        orders = orders.Where(o => o.StatusId == StatusId);
    if (OrderCreaatorIds != null)
        orders = orders.Where(o => OrderCreaatorIds.Contains(o.CreatorId));

    var orderItems = _db.OrderItems;
    if (OrderItemCategoryIds != null)
        orderItems = orderItems.Where(oi => OrderItemCategoryIds.Contains(oi.CategoryId));

    var query = from s in _db.Shops
                join o in orders on s.Id equals o.ShopId
                join oi in orderItems on o.Id equals oi.OrderId
                select s.Id;

    return query.ToArray();
}