Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Linq To Entities / 14 сообщений из 14, страница 1 из 1
21.05.2011, 22:34
    #37272962
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Хочу выбрать похожие статьи по тэгам:
Код: plaintext
1.
var model = _db.Articles.Include("Author").Include("Tags").FirstOrDefault();

Здесь выбираю статью (опустил where).
Теги к статьям M:M.
Код: plaintext
1.
2.
3.
4.
5.
public class Tag
{
     public int Id { get; set; }
     public String Name { get; set; }
     public ICollection<Article> Articles { get; set; }
}

Как написать запрос, чтобы выбрать статьи, которые имеют тот же набор тегов?
Спасибо.
...
Рейтинг: 0 / 0
23.05.2011, 14:33
    #37274519
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Кто-нибудь может помочь? Может какие-нибудь идеи?

Или инфы недостаточно?
...
Рейтинг: 0 / 0
23.05.2011, 16:08
    #37274789
Вестник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
одним запросом? сколько у вас статей и сколько у каждой в среднем тэгов?
...
Рейтинг: 0 / 0
23.05.2011, 20:12
    #37275320
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Вестникодним запросом? сколько у вас статей и сколько у каждой в среднем тэгов?
В идеале одним. Циклом по каждому тегу или каждой статье не хочется генерировать запросы. Статей пока около 30. Тегов поменьше. Но понятно, что и статей больше будет и тегов. Поэтому хочется раз и на всегда решить вопрос.

Пробовал несколькими способами. Но каждый раз одна и та же ошибка:
Код: plaintext
1.
var same = _db.Articles.Where(a => a.Tags == model.Tags);
Ошибка: Не удалось создать константу с типом "ClearBoth.Models.Tag". В этом контексте поддерживаются только типы-примитивы ("например Int32, String и Guid").

Пробовал и так:
Код: plaintext
1.
var same = _db.Articles.Where(a => a.Tags.All(t => model.Tags.Contains(t)));
Ошибка та же.
...
Рейтинг: 0 / 0
23.05.2011, 20:14
    #37275322
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Понимаю, что linq to entites не понимает, как сранивать. Надо как-то сравнивать по id тега. Но запрос построить не могу. Ни методами ни linq.
...
Рейтинг: 0 / 0
23.05.2011, 21:06
    #37275388
bured
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Тот же набор тегов можно проверить с помощью пары методов Intercept и Except
...
Рейтинг: 0 / 0
23.05.2011, 21:26
    #37275411
Вестник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
я не понял вопрос: вам нужно найти все статьи по образцу или все пары/тройки/etc, у которых совпадают наборы тэгов?
...
Рейтинг: 0 / 0
23.05.2011, 21:36
    #37275418
Вестник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
buredТот же набор тегов можно проверить с помощью пары методов Intercept и Exceptнужно среди множества наборов выделить все, совпадающие с данным. не совсем понятно, как это сделать с помощью этой пары методов одним запросом
...
Рейтинг: 0 / 0
23.05.2011, 22:09
    #37275436
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Вестникя не понял вопрос: вам нужно найти все статьи по образцу или все пары/тройки/etc, у которых совпадают наборы тэгов?
Нужно выбрать статьи, которые имеют точно такой же набор тегов, ни одним больше или меньше.
Если одним запросом нельзя, то можно двумя. Можно даже от безвыходности пробежаться в цикле по всем статьям, но это уж совсем от бессилия.
...
Рейтинг: 0 / 0
23.05.2011, 22:18
    #37275450
Вестник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
пробежаться в цикле по всем статьям
запрос, если его удастся написать, сделает именно это. на ваших объемах (меньше 10000 статей) это будет почти мгновенно
...
Рейтинг: 0 / 0
23.05.2011, 22:23
    #37275465
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Извините все.

Проблему решил.
Но тут еще оказалось, что не весь набор должен совпадать, а хотя бы один тег.
Решение такое же (может даже можно поюзать All вместо Any, чтобы решить первоначальную проблему):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
List<int> idsl = new List<int>();
foreach (var tag in model.Tags)
    {
         idsl.Add(tag.Id);
    }
int[] ids = idsl.ToArray();

var same = _db.Articles.Where(a => a.Tags.Any(t => ids.Contains(t.Id)));
...
Рейтинг: 0 / 0
23.05.2011, 22:29
    #37275477
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Селект получился такой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
{SELECT 
 1  AS [C1], 
[Extent1]. AS , 
[Extent1].[Name] AS [Name], 
[Extent1].[Text] AS [Text], 
[Extent1].[CreationTime] AS [CreationTime], 
[Extent1].[PublishedDate] AS [PublishedDate], 
[Extent1].[IsPublished] AS [IsPublished], 
[Extent1].[IsTranslated] AS [IsTranslated], 
[Extent1].[Author_Id] AS [Author_Id]
FROM [dbo].[Articles] AS [Extent1]
WHERE  EXISTS (SELECT 
	 1  AS [C1]
	FROM [dbo].[TagArticles] AS [Extent2]
	WHERE ([Extent1]. = [Extent2].[Article_Url]) AND ([Extent2].[Tag_Id] IN ( 3 , 4 ))
)}
...
Рейтинг: 0 / 0
23.05.2011, 22:34
    #37275486
Вестник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
вот такая идея на sql:

таблицы:
Articles (int ArticleId)
Tags (int TagId)
ArticleTags (int ArticleId, int TagId)

ModelId - статья образец

Код: plaintext
int counter = select count(*) from ArticleTags where ArticleId = ModelId

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select ArticleId
from ArticleTags
where TagId in (select TagId from ArticleTags where ArticleId = ModelId)
   and ArticleId not in (select ArticleId 
                              from ArticleTags
                              where TagId not in (select TagId from ArticleTags where ArticleId = ModelId))
group by
    ArtcleId
having 
    count(*) = counter

оптимизатор скорее всего развернет этот запрос в несколько временных таблиц и работать будет намного дольше прямого перебора.

обязательное условия - теги в статья не повторяются (т.е. unique(TagId, ArticleId))

оно вам надо?
...
Рейтинг: 0 / 0
24.05.2011, 07:21
    #37275797
_dirty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linq To Entities
Вестник,

Спасибо. Я приму к сведению
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Linq To Entities / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]