【问题标题】:Putting multiple values in a WHERE clause in Azure Mobile Services在 Azure 移动服务的 WHERE 子句中放置多个值
【发布时间】:2013-03-02 09:40:26
【问题描述】:

我试图弄清楚如何将多个值放入WHERE 子句中;这就是您在 SQL 中使用IN 子句的类型。

我当前的代码:

if (Log.Count() == 1)
{
    items = itemTable
        .Where(Item => Item.id == Log[0].i_id)
        .ToCollectionView();
}
else if (Log.Count() == 2)
{
    items = itemTable
        .Where(Item => Item.id == Log[0].i_id || Item.id == Log[1].i_id)
        .ToCollectionView();
}
else if (Log.Count() == 3)
{
    items = itemTable
        .Where(Item => Item.id == Log[0].i_id || Item.id == Log[1].i_id || Item.id == Log[2].i_id)
        .ToCollectionView();
}

这很恶心。如果没有大的 if 语句,我找不到将多个值放入 WHERE 子句的方法。有什么想法吗?

【问题讨论】:

    标签: c# .net linq azure azure-mobile-services


    【解决方案1】:

    试试这个:

    items = itemTable
        .Where(Item => Log.Any(logItem => logItem.i_id == Item.id))
        .ToCollectionView();
    

    编辑:(响应“不支持的异常”)

    你可以试试这个替代方案,看看后端是否支持它:

    var ids = Log.Select(logItem => logItem.i_id).ToList();
    var items = itemTable
        .Where(Item => ids.Contains(Item.id))
        .ToCollectionView();
    

    【讨论】:

    • 经过一番调查,似乎是触发它的 Any 方法中的参数。使用items = itemTable .Where(Item => Log.Any)) .ToCollectionView(); 不会出错。
    • @user2070752 对,对于IQueryable,答案取决于查询处理器支持的内容。没有给出错误的查询是否返回了您预期的结果?
    • 我预期的结果,是的。我需要的结果,没有。这很奇怪,因为Log.Any(logItem => logItem.i_id == Item.id) 也能正常工作,只是不是items = itemTable .Where(Item => Log.Any(logItem => logItem.i_id == Item.id)) .ToCollectionView() 的一部分。
    • @user2070752 查看编辑以检查其他选择是否更好。
    • 同样的问题。我正在用 C# 在 Visual Studio 2012 中为 WP8 编程。我不知道这是否重要。
    【解决方案2】:
    items = itemTable.Where(Item => Log.Any(i => i.i_id == Item.id)).ToCollectionView();
    

    【讨论】:

    • 对了,应该是i => i.i_d == ...
    • @user2070752,我已经在 WP8 和 VS2012 下尝试过这个查询,以获得简化的示例 itemTable 和 Log 的数据,并且这个查询工作正常。我还没有检查ToCollectionView(),所以你可以看看是不是ToCollectionView() 抛出了NotSupportedException?
    • 使用 ToListAsync() 时同样的问题。我从 Azure 获取我的表,所以这会是他们的问题吗?
    【解决方案3】:

    我遇到了同样的问题。像其他人建议的那样使用 Any 或 Contains 给了我一个不支持的异常。我在 Azure 移动服务论坛上发帖,被告知尚不支持 IN。他们建议我使用一种非常适合我的扩展方法。下面是我使用的代码。

     public static class Extensions
    {
        public async static Task<List<T>> In<T>(this IMobileServiceTable<T> table, List<int> ids)
        {
            var query = new StringBuilder("$filter=(");
            for (int i = 0; i < ids.Count; i++)
            {
                query.AppendFormat("id eq {0}", ids[i]); //don't forget to url escape and 'quote' strings
                if (i < ids.Count - 1)
                {
                    query.Append(" or ");
                }
            }
            query.Append(")");
            var list = await table.ReadAsync(query.ToString());
            var items = list.Select(i => MobileServiceTableSerializer.Deserialize<T>(i)).ToList();
            return items;
        }
    }
    

    您的列表可以通过调用扩展方法来填充,如下所示:

    FavoriteJokesList = await jokeItemTable.In(favoriteJokeIds);
    

    来源:http://social.msdn.microsoft.com/Forums/en-US/azuremobile/thread/b573ff6c-1f6b-4846-b44d-4678e3d26f66

    【讨论】:

      【解决方案4】:

      仅作记录,在最新版本的 Azure 移动服务 SDK (1.0) 中,这是可行的:

      var ids = Log.Select(logItem => logItem.i_id).ToList();
      var items = await itemTable
      .Where(Item => ids.Contains(Item.id))
      .ToCollectionAsync();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-10
        • 2022-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-17
        • 1970-01-01
        相关资源
        最近更新 更多