Я застрял в этой проблеме уже пару дней. Я пытаюсь сделать следующее:
Рассмотрим следующие классы С#, соответствующие документам в MongoDB. Торговцы хранятся в коллекции торговцев, и все они содержат массив валют.
class Merchant
{
public string id {get;set;}
public List<Currency> MerchantCurrencies {get; set; }
}
class Currency
{
public string id {get; set; }
public string name {get; set; }
...
}
Теперь, что я хочу сделать, нужно вернуть все валюты всех продавцов в рамках одного запроса с LINQ. Я пробовал такие вещи, как SelectMany и несколько из предложений, например:
var currencies = merchantCollection.AsQueryable()
.SelectMany(m => m.MerchantCurrencies)
.Where(ccy => ccy.CurrencyState == currencyStatus)
.OrderBy(ccy => ccy.CurrencyName);
а также
var currencies= from merch in merchantCollection.AsQueryable()
from ccy in merch.MerchantCurrencies
select ccy
Однако все эти вещи не работают, поскольку они основаны на SelectMany, который использует объединения. Использование SelectMany вызовет исключение, поскольку оно не поддерживается драйвером MongoDB С#.
Есть ли какое-либо решение моей проблемы, помимо использования структуры агрегации/сокращения карты/нескольких запросов?
Единственное решение, которое я нашел, было:
1. Получение всех купцов
2. Прокрутите торговцев
3. Перемещайтесь по их валютам
4. Добавьте валюты в другую переменную списка
Тем не менее, мне не нравится этот подход, потому что мне придется получить все коммерческие объекты, которые являются довольно дорогостоящей операцией, если это огромная коллекция.
С уважением
Отказ от ответственности: я знаю 0 о С# и LINQ
Тем не менее, есть встроенная функция для выполнения того, что вы хотите: distinct
. За отказ от ответственности я проиллюстрирую в оболочке монго:
> db.test.drop()
> db.test.insert({ "a" : [{ "a" :1 , "b" : 2 }, "op", 2, "3", "goop"] })
> db.test.insert({ "a" : [1,2, 3, "goop"] })
> db.test.distinct("a")
[ 1, 2, 3, "goop", "3", "op", { "a" : 1, "b" : 2 } ]
> db.test.distinct("a", { "a" : "op" })
[ 2, "3", "goop", "op", { "a" : 1, "b" : 2 } ]
Он делает ваши 1-4, но на стороне сервера, по существу - другого способа получить отдельные значения документов, кроме тех случаев, когда работа уже частично выполнена, потому что там индекс, не может быть другого способа. Если у вас есть индекс в { "a": 1 }
в приведенном выше примере, distinct
могут использовать это, чтобы найти различные значения с помощью сканирования индекса вместо сканирования коллекции.
Я думаю, что С# метод, который вы хотите, это один.
Кажется, вы пытаетесь использовать базу данных NoSQL для хранения реляционных данных, что может быть не очень хорошая идея. Если вы хотите придерживаться MongoDB, я бы рекомендовал добавить новую коллекцию всех разных валют и обновить ее по мере необходимости.
Ознакомьтесь с этой ссылкой на документацию MongoDB, которая описывает ту же проблему.
MongoDB не поддерживает объединения, и поэтому время от времени требуется бит денормализации. Коллекции MongoDB не эквивалентны реляционным таблицам; каждая из которых служит уникальной проектной цели. Нормализованная таблица обеспечивает атомный изолированный кусок данных. Однако документ более тесно представляет собой объект в целом.