Linqtosql - Найти все объекты, соответствующие всем тегам в запросе - PullRequest
0 голосов
/ 18 мая 2009

У меня есть классическая таблица 3 - entity, tag и entitytag - структура базы данных.

Чтобы найти все объекты, помеченные определенными тегами, я использую следующий код Linqtosql:

string[] myTags = {"tag1","tag2"};

var query = from m in entity
            where m.entitytag.Where(c => myTags.Contains(c.tag.TagName)).Count() == myTags.Count()
            select m;

Однако, когда у сущностей есть дубликаты тегов (в моем реальном приложении есть веская причина) запрос возвращает сущности, которые не соответствуют всем тегам.

например, в приведенном выше примере кода, если объект был помечен дважды тегом «tag1», а не «tag2», он вернется в результатах, несмотря на несоответствие обоих тегов.

Не могу понять, как исключить эти объекты из результатов?

Или я должен придерживаться совершенно другого подхода?

Ответы [ 4 ]

1 голос
/ 18 мая 2009

Попробуйте вместо этого запрос:

                    string[] myTags = { "tag1", "tag2" };
                    var query = from m in entity
                                where myTags.All(tag => m.entitytag.Contains(tag))
                                select m;
                    query.Dump();

Метод All extension обеспечивает то, что каждый тег удовлетворяет критериям содержания.

Существует также метод расширения Any для случаев, когда требуется только один критерий.

Надеюсь, это поможет.

Каван

0 голосов
/ 04 июня 2009

Попробуйте

string[] myTags = { "tag1", "tag2" };

var query = from e in entity
            where !myTags.Except(from e.tag select e.tag.TagName).Any()
            select e;

Идея состоит в том, чтобы удалить теги объекта из копии myTags. Любые элементы, оставшиеся после этого, соответствуют тегам, которые отсутствуют в сущности.

Хотя я не знаю, как это работает.

0 голосов
/ 18 мая 2009

Как предполагает Eoin, необходимо использовать Distinct (), но он не работает с целыми наборами тегов лица. Использование другого оператора Select только для сравнения с фактическим тегом - вот хитрость.

    string[] myTags = {"tag1","tag2"};

    var query = from m in entity
    where m.entitytag.Select(et => et.tag.TagName).Distinct().Where(c => myTags.Contains(c)).Count() == myTags.Count()
    select m;

К сожалению, недостатком является то, что это несколько снижает производительность.

0 голосов
/ 18 мая 2009

Как насчет изменить его на

where m.entitytag.Distinct().Where(c => ...

, который удалит дубликаты тегов сущностей из вашей коллекции объектов и позволил вашему счетчику работать должным образом

...