Сначала EF-код — сопоставление равенства объединения с объектами

#c# #linq #linq-to-entities #union #ef-code-first

#c# #linq #сопоставление с объектами #объединение #сначала ef-код

Вопрос:

У меня есть две IEnumerable коллекции, которые я хотел бы объединить.

Выбираются новостные объекты, которые связаны с определенной категорией. Когда пользователь выполняет фильтрацию по категории, я бы также хотел, чтобы отображались новостные статьи, помеченные другой категорией.

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

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

  var catNews = model.Category.News.SelectMany(n => n.News); //get news article associated to the category
 var tagNews = _nr.GetNews(model.Category.relatedCategoryName); //this selects news by tags - which I want as the related category name
 model.News = catNews.Union(tagNews).OrderByDescending(p => p.Date); //union the two collections
  

Однако модель.Новости теперь содержат две идентичные новостные статьи, и я не уверен, почему as union должен использовать средство сравнения равенства по умолчанию?

Я делаю что-то не так здесь? Сначала я использую EF-код, и моим первичным ключом является идентификатор новости.

Я решил эту проблему, передав список идентификаторов catNews в функцию GetNews и исключив их

 if (excludeIds != null)
    q = q.Where(n => !excludeIds.Contains(n.ID));
  

Но я не уверен, зачем мне это, когда я думал, что union удалит идентичные статьи?

Ответ №1:

Я предполагаю, что вы не загружаете эти две коллекции из одного и того же экземпляра контекста entity framework. Средство сравнения равенства по умолчанию будет сравнивать ссылки, и если вы используете один и тот же контекст, оно действительно вернет один и тот же News экземпляр в обеих коллекциях при Id совпадении, но если вы используете разные контексты, каждая коллекция будет содержать свои собственные News экземпляры и Union будет делать то же самое, что и Concat . В таком случае вы должны переопределить Equals GetHaschCode ) в вашей News сущности для сравнения Id или использовать пользовательский компаратор.