Linq израз вместо SQL с присъединяване и масив

Има ли начин да формулирате следния SQL оператор за DocumentDB с Linq (за DocumentDB)?

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

Това се основава на моя въпрос и е отговор от DocumentDB заявки с масиви.


person Thomas Mutzl    schedule 01.09.2015    source източник
comment
Моля, споделете и вашата схема.   -  person Arnab Chakraborty    schedule 17.09.2015


Отговори (3)


В моето (много общо) хранилище изграждам динамично някои сложни изрази за предикатите 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);
person Thomas Mutzl    schedule 17.09.2015

Ако имате клас като този

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\")");

Можете да намерите повече информация за това как да създавате заявки в DocumentDb в този връзка

person octavioccl    schedule 01.09.2015

От версия 1.4.0 на .NET SDK вече се поддържа следното -

string[] ids = new string[] { "1", "2", "3", "4", "5"};
var query = client.CreateDocumentQuery(collLink).Where(d => ids.Contains(d.Id);
person Ryan CrawCour    schedule 01.09.2015
comment
Знам, Райън. Но трябва да попитам дали даден масив съдържа (поне) един елемент от друг масив. - person Thomas Mutzl; 02.09.2015