documentdb与linq连接

时间:2015-09-16 09:18:37

标签: c# linq azure-cosmosdb

我正在尝试使用linq

在DocumentDb上运行以下查询
SELECT p.id 
FROM p JOIN filter IN p.Filters
WHERE filter.Id = "686e4c9c-f1ab-40ce-8472-cc5d63597263" 
OR filter.Id = "caa2c2a0-cc5b-42e3-9943-dcda776bdc20"

我的json是这样的

 {
  "id": "a3dc570b-26e2-40a9-8777-683186965f78",
  "Filters": [
    {
      "Id": "686e4c9c-f1ab-40ce-8472-cc5d63597263"
    },
    {
      "Id": "caa2c2a0-cc5b-42e3-9943-dcda776bdc20"
    }
  ]
}

我发现我应该使用SelectMany进行加入,但是我无法让它工作,我尝试了不同的东西,但总是会遇到运行时错误。

编辑: 这是我尝试过的查询,这给出了"指定的参数超出了有效值的范围。参数名称:意外的Sql标量表达式种类转换"

    public void TryOutQuery(IEnumerable<string> ids)
    {
        var options = new FeedOptions { MaxItemCount = 10, RequestContinuation = "" };
        var queryable = _client.CreateDocumentQuery<PostModel>(UriFactory.CreateCollectionUri(_collectionConn.DatabaseName, _collectionConn.CollectionName), options)                
            .SelectMany(p => p.Filters
            .Where(f => ids.Contains(f.Id))
            .Select(f => p)
            .Where(post => post.Status == PostStatus.Published)
            )
            ;
        var query = queryable.AsDocumentQuery();
        var asyn = query.ExecuteNextAsync<PostModel>();
        var result = asyn.Result; 
    }

我还尝试了另一个命令,它为查询输出类型提供了&#34;不一致的类型:Post.PostModel和Post.Filter&#34;

    public void TryOutQuery(IEnumerable<string> ids)
    {
        var options = new FeedOptions { MaxItemCount = 10, RequestContinuation = "" };
        var queryable = _client.CreateDocumentQuery<PostModel>(UriFactory.CreateCollectionUri(_collectionConn.DatabaseName, _collectionConn.CollectionName), options)
            .Where(p => p.Status == PostStatus.Published)
            .SelectMany(p => p.Filters
            .Where(f => ids.Contains(f.Id))
            .Select(f => p)                
            )
            ;
        var query = queryable.AsDocumentQuery();
        var asyn = query.ExecuteNextAsync<PostModel>();
        var result = asyn.Result; 
    }

这是我的模特

public class Filter
{
    public Filter(string id)
    {
        Id = id;
    }       
    public String Id { get; set; }
}

public class PostModel
{    
    public PostModel()
    {
        _filters = new List<Filter>();
    }
    [JsonProperty("id")]
    public String Id { get; set; }
    //Since DocumentDb doesn't work properly with IList
    public IEnumerable<Filter> Filters { get { return _filters; } }
    private IList<Filter> _filters;
    public PostStatus Status { get; set; }

    public void AddFilter(string filterId)
    {
        _filters.Add(new Filter(filterId));
    }

}

public enum PostStatus
{
    Draft,
    Published,
    Deleted
}

1 个答案:

答案 0 :(得分:3)

我将使用带有两个JOIN和过滤器的查询作为示例:

// SQL
var familiesChildrenAndPets = client.CreateDocumentQuery<dynamic>(collectionLink,
        "SELECT f.id as family, c.FirstName AS child, p.GivenName AS pet " +
        "FROM Families f " +
        "JOIN c IN f.Children " +
        "JOIN p IN c.Pets " +
        "WHERE p.GivenName = 'Fluffy'");

// LINQ
var familiesChildrenAndPets = client.CreateDocumentQuery<Family>(collectionLink)
        .SelectMany(family => family.Children
        .SelectMany(child => child.Pets
        .Where(pet => pet.GivenName == "Fluffy")
        .Select(pet  => new
        {
            family = family.Id,
            child = child.FirstName,
            pet = pet.GivenName
        }
        )));

查看此DocumentDB Github仓库以获取更多examples