powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Исключить из выборки записи другой выборки
11 сообщений из 11, страница 1 из 1
Исключить из выборки записи другой выборки
    #38675293
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть список адресов
Есть группы, в которые эти адреса могут входить.
Адрес может входить в несколько групп.
Когда добавляем в группу адрес, хочется показывать адреса, которые не входят в данную группу.
Ничего не придумал лучше, как написать монструальный код:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
            IEnumerable<GroupEmailCust> eMailAll = GetGroup();
            IEnumerable<GroupEmailCust> eMailGrp = eMailAll.Where(c => c.CustomGroupID == id);
            IEnumerable<GroupEmailCust> eMailNotGrp = eMailAll;

            foreach (var cust in eMailGrp)
            {
                eMailNotGrp = eMailNotGrp.Where(g => g.EMailID != cust.EMailID).OrderBy(c=>c.Custom);
            }
            return eMailNotGrp;


Все работает, но foreach... как то смущает.
Не по фэн шую)))
Хотя записей не много, ничего не тормозит.
Но как вычесть из одного множества, по определенным признакам другое, не пойму(
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675303
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверное совсем мало инфы выложил.
вот получение GetGroup
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
       public IEnumerable<GroupEmailCust> GetGroup()
        {
            var eMail = from b in db.bCustoms
                        join m in db.EMails
                            on b.CustomID equals m.CustomID
                        join g in db.MailToGroups
                            on m.EMailID equals g.EMailID into t1
                        from g1 in t1.DefaultIfEmpty()
                        where m.ismark==0 
                        select new GroupEmailCust
                        {
                            EMailID = m.EMailID,
                            CustomID = m.CustomID,
                            Custom = b.txt,
                            Mail = m.Mail,
                            Name = m.Name,
                            CustomGroupID = g1.CustomGroupID
                        };
            return eMail;
        }
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675441
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asdor
Код: c#
1.
2.
3.
4.
5.
            foreach (var cust in eMailGrp)
            {
                eMailNotGrp = eMailNotGrp.Where(g => g.EMailID != cust.EMailID).OrderBy(c=>c.Custom);
            }
            return eMailNotGrp;



заставило меня задуматься о смысле жизни...

может вот это поможет?

https://www.google.ru/?q=linq exclude one list from another
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675525
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
foreach и на меня наводит грусть.

Я не знаю, как уточнить поиск, что бы найти нужное.
Но в приведенном, не совсем то что мне требуется.
Видимо не до конца проблему описал.
Есть таблицы:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
   public partial class bCustom //Контрагенты
    {
        public int CustomID { get; set; }
        public string txt { get; set; }
    }

    public partial class EMai l//Адреса. У контрагента может быть несколько. Не принципиально в данном случае
    {
        public int EMailID { get; set; }
        public int CustomID { get; set; }
        public string Mail { get; set; }
        public string Name { get; set; }
    }

    public partial class CustomGroup //Группы рассылки
    {
        public int CustomGroupID { get; set; }
        public string Name { get; set; }
    }

   public  class MailToGroup //связь Группы-Адреса
    {
        public int MailToGroupID { get; set; }
        public int EMailID { get; set; }
        public int CustomGroupID { get; set; }
    }



Один и тот же адрес, может быть в нескольких группах 1:М
Все свел к таким ModelView
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  public class EmailCust
    {
        [Key]
        public int EMailID { get; set; }
        public int CustomID { get; set; }
        [Display(Name = "Контрагент")]
        public string Custom { get; set; }
        [Display(Name = "Email")]
        public string Mail { get; set; }
        [Display(Name = "Контактное лицо")]
        public string Name { get; set; }
    }

    public class GroupEmailCust:EmailCust
    {
        public int? CustomGroupID { get; set; }
    }



Теперь требуется показать, все имеющиеся адреса (GroupEmailCus) которых нет в данной группе.
Если делать, как в приведенных примерах, то будет не до конца верно.
Попробую на пальцах.
Есть группы:
1 Асфальт
2 Бетон
Есть адреса:
1 a@some.com
2 b@some.com
3 c@some.com

В Асфальт вносим
1 a@some.com
2 b@some.com
В Бетон вносим
1 a@some.com
3 с@some.com
В MailToGroup получим
1 1
1 2
2 1
2 3

Теперь хотим добавить адрес в Асфальт
Значит надо показать всех, кто в нем не содержится
Т.е. 3 c@some.com
Но в при вычитании, мы получим еще и a@some.com, которое привязано, к Бетону
Т.е. надо не просто из eMailAll вычесть eMailGrp, а убрать из eMailAll все записи, с EMailID имеющимися в eMailGrp

Боюсь опять не ясно объяснил, но я старался)
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675533
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Нашел вариант с подзапросом.
Не знал как его на Linq реализовать.
Но по сути, это ж, тот же foreach...
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675545
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asdor,

дано

AllMails -- коллекция все ящики
MailToGroups -- коллекция соединения группа-ящик
и
нужная группа: CustomGroupID = 1

надо получить все мейлы, не в группе 1, так?

Код: c#
1.
2.
3.
4.
var query = from m in AllMails
                 join g in MailToGroups on m.EMailID equals g.EMailID
                 where g.CustomGroupID != 1
                 select m;



в query у тебя все ящики, которых нет в группе 1.

если надо зацепить еще те ящики, которых нет ни в одной группе, тогда так:

Код: c#
1.
2.
3.
4.
5.
var query = from m in AllMails
                 join g in MailToGroups on m.EMailID equals g.EMailID into gg
                 from g in gg.DefaultIfEmpty()
                 where g == null || g.CustomGroupID != 1
                 select m;



вуаля.
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675560
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asdor,

ещё прощё отак уот можно сделать и обойтись без дистинктов там всяких

Код: c#
1.
2.
3.
var query = from m in AllMails
                 where !MailToGroups.Any(x => x.EMailID == m.EMailID && g.CustomGroupID != 1)
                 select m;



на первый взгляд тот же подзапрос в переборе, но ет тока на первый взгляд
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675579
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Ну чувствовал, что где то рядом)))
Очень похоже, сейчас попробую.
Спасибо
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675625
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttasdor,

ещё прощё отак уот можно сделать и обойтись без дистинктов там всяких

Код: c#
1.
2.
3.
var query = from m in AllMails
                 where !MailToGroups.Any(x => x.EMailID == m.EMailID && g.CustomGroupID != 1)
                 select m;



на первый взгляд тот же подзапрос в переборе, но ет тока на первый взгляд

Верная подсказка.
Про дистинг. Я и забыл.
И это предложение отрабатывает на ура.
Единственно что, заметно на глаз, тормоз(
Гораздо медленнее предыдущего варианта, и медленнее foreach
(Хотя в тех вариантах забыл про дистинг, и там были одинаковые адреса, собранные из других групп)
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675645
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asdorЕдинственно что, заметно на глаз, тормоз(

странно

вариант с Any() при отображении в СУБД превращается в весьма эффективный запрос. просто у тебя MailToGroups видимо не материализованный IEnumerable (сделай ToList) или пробуй вот ето:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var query = from m in AllMails
                 join g in MailToGroups on m.EMailID equals g.EMailID into gg
                 from g in gg.DefaultIfEmpty()
                 where g == null || g.CustomGroupID != 1
                 select m.EMailID;

var list = (from m in AllMails
              join p in query.Distinct() on m.EMailID equals p
              select m)
          .ToList();



проверь мож побыстрее будет.
...
Рейтинг: 0 / 0
Исключить из выборки записи другой выборки
    #38675671
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
Вот никогда не думал, что в этом дело может быть.
Спасибо.
Материлизовал MailToGroups в лист, все поехало.
Главное лаконично)

Спасибо.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Исключить из выборки записи другой выборки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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