【问题标题】:Linq statement instead of SQL with join and arrayLinq 语句而不是带有连接和数组的 SQL
【发布时间】:2015-09-17 20:01:35
【问题描述】:

有没有办法用 Linq(针对 DocumentDB)为 DocumentDB 制定以下 SQL 语句?

SELECT docs
FROM docs
JOIN tags IN docs.tags
WHERE tags IN ("B", "C")

这是基于我的问题和来自DocumentDB queries with arrays 的回答。

【问题讨论】:

  • 请也分享您的架构。

标签: sql linq azure azure-cosmosdb


【解决方案1】:

在我的(非常通用的)存储库中,我为 WHERE 谓词动态构建了一些复杂的表达式。 因此,手动创建 SQL 语句并不是一个真正的选择。

所以我最终使用了用户定义的函数。

在集合中定义的 UDF,ID:CONTAINSANY

function containsAny (source, target) {
    if (source == null || target == null) return false;
    return target.some(function(item) { return source.indexOf(item) >= 0; } );
}

客户端调用:

var udfName = "CONTAINSANY";    
var tags = new[] { "B", "C" };
var query = client.CreateDocumentQuery(collLink)
     .Where(item => (bool)UserDefinedFunctionProvider.Invoke(udfName, item.tags, tags);

【讨论】:

    【解决方案2】:

    如果你有这样的课程

    public class Doc
    {
        [JsonProperty(PropertyName = "id")]
        public string Id { get; set; }
        public string[] Tags{ get; set; }
    }
    

    你可以这样做:

    private string EndpointUrl = "<your endpoint URI>";
    private string AuthorizationKey = "<your key>";
    private string database = "<DB Id>";
    private string CollectionID= "<Collection Id>";
    
    //prepare document db client
    DocumentClient pClient = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);
    
    //prepare document db database
    Database pDatabase = pClient.CreateDatabaseQuery().Where(db => db.Id == database).AsEnumerable().FirstOrDefault();
    
    //prepare document db collection
    DocumentCollection documentCollection= pClient.CreateDocumentCollectionQuery(pDatabase.SelfLink).Where(c => c.Id == CollectionID).ToArray().FirstOrDefault();
    
    var tags = new[] { "B", "C" };
    var families =  client.CreateDocumentQuery<Doc>(documentCollection.DocumentsLink)
                   .SelectMany(doc=>doc.Tags.Where(t=> tags.Contains(t));
    

    现在我不确定 Contains 方法是否已被 Linq 提供程序支持(我找不到任何关于此的文档),但如果没有,也许你可以通过这种方式完成你的 where 条件:

    .Where(t=>t=="B" || t=="C") 
    

    我知道这并不理想,但应该可以。所有这些东西都很新,我们必须稍等片刻才能看到更多文档和更多我们可以使用的功能。

    同时,始终可以选择直接执行您的查询:

    var items = client.CreateDocumentQuery<dynamic>(documentCollection.DocumentsLink,
        "SELECT docs" +
        "FROM docs" +
        "JOIN tags IN docs.tags" +
        "WHERE tags IN (\"B\", \"C\")");
    

    您可以在 link 中找到有关如何在 DocumentDb 中创建查询的更多信息

    【讨论】:

      【解决方案3】:

      从 .NET SDK 的 v 1.4.0 开始,现在支持以下内容 -

      string[] ids = new string[] { "1", "2", "3", "4", "5"};
      var query = client.CreateDocumentQuery(collLink).Where(d => ids.Contains(d.Id);
      

      【讨论】:

      • 我知道,瑞恩。但我需要查询一个数组是否包含(至少)另一个数组的一个元素。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多