Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Исключить из выборки записи другой выборки / 11 сообщений из 11, страница 1 из 1
20.06.2014, 12:41
    #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
20.06.2014, 12:44
    #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
20.06.2014, 14:13
    #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
20.06.2014, 14:53
    #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
20.06.2014, 14:57
    #38675533
asdor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Исключить из выборки записи другой выборки
hVostt,
Нашел вариант с подзапросом.
Не знал как его на Linq реализовать.
Но по сути, это ж, тот же foreach...
...
Рейтинг: 0 / 0
20.06.2014, 15:07
    #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
20.06.2014, 15:16
    #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
20.06.2014, 15:25
    #38675579
asdor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Исключить из выборки записи другой выборки
hVostt,
Ну чувствовал, что где то рядом)))
Очень похоже, сейчас попробую.
Спасибо
...
Рейтинг: 0 / 0
20.06.2014, 15:50
    #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
20.06.2014, 15:59
    #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
20.06.2014, 16:13
    #38675671
asdor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Исключить из выборки записи другой выборки
hVostt,
Вот никогда не думал, что в этом дело может быть.
Спасибо.
Материлизовал MailToGroups в лист, все поехало.
Главное лаконично)

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


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