Microsoft MVP성태의 닷넷 이야기
Linq Entites 에서 string[]에 담긴 데이터를 제외하는 방법 문의 [링크 복사], [링크+제목 복사],
조회: 4216
글쓴 사람
권용완 (yongwan.kwon at koroi.com)
홈페이지
첨부 파일
 

안녕하세요.
어제 구구절절 질문/답변에 글 올렸다가 삭제후 내용정리 하여 다시 올립니다. ㅠㅠ
회사 업무프로그램을 독학으로 개발하려고 하니 어려움이 있어 도움을 청하고자 합니다.

원하는 데이터는 IsFinalOrder = true 인 데이터의 같은 QuoteNumber 값을 같는 데이터를 제거 하고자 합니다.
필터링(제외) 해야할 데이터를 Tolist()로 담았다가 다시 ToArray() 배열 string[] filter 변수에 담았습니다.

query 변수에 람다식의 Where문으로 filter 배열에 담긴 내용을 제거 하고자 합니다.

제가 얻고자 하는 데이터는 아래와 같습니다.


내연기관자동차부품 로봇자동화 KR22-002 1 1500000 False
내연기관자동차부품 로봇자동화 KR22-002 2 1400000 False
내연기관자동차부품 로봇자동화 KR22-002 3 1300000 False
내연기관자동차부품 로봇자동화 KR22-002 4 1250000 False
밧데리부품 로봇자동화 KR22-003 1 1000000 False

위와 같이 데이터를 뽑아야 하는데..잘 되지 않네요. 조언 부탁드립니다.



-------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinqDemo2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var customer = new List<Customer>
            {
                new Customer{ID = 1, BusinessName = "JS전자", CEOName = "유재석"},
                new Customer{ID = 2, BusinessName = "HD전자", CEOName = "강호동"},
                new Customer{ID = 3, BusinessName = "SG전자", CEOName = "이수근"},
            };
            var quotationName = new List<QuotationName>
            {
                new QuotationName{ID = 1, QuoteName = "전기자동차부품 로봇자동화" ,QuoteNumber = "KR22-001", CustomerID = 1},
                new QuotationName{ID = 2, QuoteName = "내연기관자동차부품 로봇자동화" ,QuoteNumber = "KR22-002", CustomerID = 2},
                new QuotationName{ID = 3, QuoteName = "밧데리부품 로봇자동화" ,QuoteNumber = "KR22-003", CustomerID = 2},
                new QuotationName{ID = 4, QuoteName = "밧데리부품 로봇자동화" ,QuoteNumber = "KR22-004", CustomerID = 3},
            };
            var quotationInformation = new List<QuotationInformation>
            {
                new QuotationInformation{ID = 1, QuoteGradation = 1, QuoteAmount = 1_200_000, IsFinalOrder = false, QuotationNameID = 1},
                new QuotationInformation{ID = 2, QuoteGradation = 2, QuoteAmount = 1_000_000, IsFinalOrder = true, QuotationNameID = 1},
                new QuotationInformation{ID = 3, QuoteGradation = 1, QuoteAmount = 1_500_000, IsFinalOrder = false, QuotationNameID = 2},
                new QuotationInformation{ID = 4, QuoteGradation = 2, QuoteAmount = 1_400_000, IsFinalOrder = false, QuotationNameID = 2},
                new QuotationInformation{ID = 5, QuoteGradation = 3, QuoteAmount = 1_300_000, IsFinalOrder = false, QuotationNameID = 2},
                new QuotationInformation{ID = 6, QuoteGradation = 4, QuoteAmount = 1_250_000, IsFinalOrder = false, QuotationNameID = 2},
                new QuotationInformation{ID = 7, QuoteGradation = 1, QuoteAmount = 1_000_000, IsFinalOrder = false, QuotationNameID = 3},
                new QuotationInformation{ID = 8, QuoteGradation = 1, QuoteAmount = 900_000, IsFinalOrder = true, QuotationNameID = 4},
            };

            // IsFinalOrder 값이 True인 QuoteNumber ( 제외할 데이터 )
            var filter = quotationInformation.Join(quotationName, i => i.QuotationNameID, n => n.ID, (i, n) => new { i, n })
                                            .Where(x => x.i.IsFinalOrder == true)
                                            .Distinct()
                                            .Select(d => d.n.QuoteNumber)
                                            .ToArray();
            foreach (var data in filter)
            {
                Console.WriteLine($"{data}");
            }
            Console.WriteLine("---------------------------------------------");

            // 데이터 조인
            var query = quotationInformation.Join(quotationName, i => i.QuotationNameID, n => n.ID, (i, n) => new { i, n })
                                            .Join(customer, n => n.n.CustomerID, c => c.ID, (nn, c) => new { nn, c })
                                            //.Where(x => x.nn.n.QuoteNumber.Any(s => queryQuoteNumberTrue.Contains(s.ToString())))
                                            //.Where(fi => fi.nn.n.QuoteNumber == queryQuoteNumberTrue.Contains(fi.ToString()))
                                            //.Where(fi => fi.nn.n.QuoteNumber.Select(fi=>fi.)
                                            //.Where(fi => !fi.nn.n.QuoteNumber.Any(f => fi.nn.n.QuoteNumber.Contains(filter[0])))
                                            //.Where(fi=>fi.nn.n.QuoteNumber.Any()))
                                            //.Where(fi=> filter.Except(y=>fi.nn.n.QuoteNumber.Contains(y)))
                                            .Select(q => new QuotationOrderDTO
                                            {
                                                QuoteName = q.nn.n.QuoteName,
                                                QuoteNumber = q.nn.n.QuoteNumber,
                                                QuoteGradation = q.nn.i.QuoteGradation,
                                                QuoteAmount = q.nn.i.QuoteAmount,
                                                IsFinalOrder = q.nn.i.IsFinalOrder
                                            })
                                            .ToList();

            foreach (var data in query)
            {
                Console.WriteLine($"{data.QuoteName} {data.QuoteNumber} {data.QuoteGradation} {data.QuoteAmount} {data.IsFinalOrder}");
            }
            Console.WriteLine("---------------------------------------------");
        }
    }

    public class Customer
    {
        public int ID { get; set; }
        public string BusinessName { get; set; }
        public string CEOName { get; set; }
        public List<QuotationName> QuotationNames { get; set; }
    }

    public class QuotationName
    {
        public int ID { get; set; }
        public string QuoteName { get; set; }
        public string QuoteNumber { get; set; }
        public int CustomerID { get; set; }
        public Customer Customer { get; set; }

        public List<QuotationInformation> QuotationInformation { get; set; }
    }

    public class QuotationInformation
    {
        public int ID { get; set; }
        public int QuoteGradation { get; set; }
        public decimal QuoteAmount { get; set; }
        public bool IsFinalOrder { get; set; }
        public int QuotationNameID { get; set; }
        public QuotationName QuotationName { get; set; }
    }

    public class QuotationOrderDTO
    {
        public string Customer { get; set; }
        public string QuoteName { get; set; }
        public string QuoteNumber { get; set; }
        public int QuoteGradation { get; set; }
        public decimal QuoteAmount { get; set; }
        public bool IsFinalOrder { get; set; }
    }
}








[최초 등록일: ]
[최종 수정일: 7/5/2022]


비밀번호

댓글 작성자
 



2022-07-05 08시33분
Join을 할 때 "KR22-001", "KR22-004" 데이터만을 제외하려고 해서 더 어려워진 것입니다.

우선, IsFinalOrder == true인 것을 찾아내고,

                var excludeOrder = from qi in quotationInformation
                             where qi.IsFinalOrder == true
                             select qi;

이것을 이용해 "KR22-001", "KR22-004" 레코드를 찾아내셨죠?

                var excludeName = from qi in excludeOrder
                                  join qn in quotationName on qi.QuotationNameID equals qn.ID
                                  select qn;

여기까지는 잘 하셨는데요, 문제는 이후에 바라보는 관점을 어렵게 잡았습니다. 애당초 Join 하려는 quotationName에서 "KR22-001", "KR22-004"를 제거한 집합을 구성하고 그것을 대상으로 Join을 시키는 것이 낫습니다. 따라서, 다음과 같이 제외시키면,

                var filteredName = quotationName.Except(excludeName);

이제 그냥 편안하게 Join만 시켜주면 끝입니다.

                var finalQuery = from qi in quotationInformation
                                 join qn in filteredName on qi.QuotationNameID equals qn.ID
                                 join cu in customer on qn.CustomerID equals cu.ID
                                 select new
                                 {
                                     qn.QuoteName,
                                     qn.QuoteNumber,
                                     qi.QuoteGradation,
                                     qi.QuoteAmount,
                                     qi.IsFinalOrder
                                 };

// 출력 결과
내연기관자동차부품 로봇자동화 KR22-002 1 1500000 False
내연기관자동차부품 로봇자동화 KR22-002 2 1400000 False
내연기관자동차부품 로봇자동화 KR22-002 3 1300000 False
내연기관자동차부품 로봇자동화 KR22-002 4 1250000 False
밧데리부품 로봇자동화 KR22-003 1 1000000 False
정성태
2022-07-06 10시20분
[권용완] 제가 너무 어렵게 생각했군요.
true인 "KR22-001" , "KR22-004" 레코드를 찾아서 Except하고 그것을 조인 하면 되네요...감사합니다.
[guest]
2022-07-06 11시16분
[권용완] 다른 방법으로 해봤습니다.
quotationInformation 리스트에는 QuotationNameID도 포함 하고 있으니 IsFinalOrder = true 인 QuotationNameID를 가져와서 배열저장하고
quotationInformation.Where(i => !excludeID.Any(x => x == i.QuotationNameID)) Where절에 Any()메서드를 포함했습니다.

그런다음 조인을 하니 제가 원하는 데이터가 나왔네요.
----------------------------------------------------
            // IsFinalOrder == true 인 QuotationNameID 값 찾기
            var excludeID = quotationInformation.Where(i => i.IsFinalOrder == true)
                                                .Select(s => s.QuotationNameID)
                                                .ToArray();

            foreach (var data in excludeID)
            {
                Console.WriteLine($"{data}");
            }
            Console.WriteLine("---------------------------------------------");


            var query = quotationInformation.Where(i => !excludeID.Any(x => x == i.QuotationNameID))
                                         .Join(quotationName, i => i.QuotationNameID, n => n.ID, (i, n) => new { i, n })
                                         .Join(customer, nn => nn.n.CustomerID, c => c.ID, (nn, c) => new { nn, c })
                                         .Select(s => new QuotationOrderDTO
                                         {
                                             Customer = s.c.BusinessName,
                                             QuoteName = s.nn.n.QuoteName,
                                             QuoteNumber = s.nn.n.QuoteNumber,
                                             QuoteGradation = s.nn.i.QuoteGradation,
                                             QuoteAmount = s.nn.i.QuoteAmount,
                                             IsFinalOrder = s.nn.i.IsFinalOrder,
                                         }).ToList();

            foreach (var data in query)
            {
                Console.WriteLine($"{data.QuoteName} {data.QuoteNumber} {data.QuoteGradation} {data.QuoteAmount} {data.IsFinalOrder}");
            }
            Console.WriteLine("---------------------------------------------");


조언 덕분에 한번더 알아 갑니다. 감사합니다.
[guest]

... 31  32  33  34  35  36  37  38  39  [40]  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
4854heyh...7/6/20179896
4853heyh...7/5/20179984성태님이 작성한대로 해봤습니다. [1]파일 다운로드1
4852김레오7/4/201712109서드파티 dll 디버깅에 대해 질문드립니다. [2]
4851김현준7/3/201711202Datagridview VirtualMode 시 GC가 계속 호출되는 현상이 이해가 안갑니다. [2]
4850heyh...7/3/201710921성태님 밑에 질문드렸던 오류입니다. [1]파일 다운로드1
4849포플러7/2/201729669C#으로 만든 프로그램이 어느 순간 속도가 느려지거나 멈춤현상이 있습니다. [4]
4848윤진영7/2/201712601Microsoft Visual C++ 6.0 무설치 관련 [1]
4847heyh...6/30/201710590아무리 고민해도 답이 안나와서.. 질문 드립니다 [1]
4846heyh...6/28/201710643Clickonce에서 Clickonce로 변수 전달 [1]
4845heyh...6/26/201710222vb.net 에서 manifest 제거 방법 [1]파일 다운로드1
4844san6/21/20179717part3 pdf파일로 보는데 눈아퍼요.... 활자로 보고싶어요 [2]
4843윤현수6/20/20179940socket통신에 관한 질문입니다. [1]
4842오세운6/7/201710632로그인폼 다시 질문드려요. [1]
4841popo6/7/201710410궁금한사항이 있어 질문 드립니다. [1]
4840윤현수6/5/201710415datagridview에 바인딩시킨 dataset.table에 관련된 질문입니다. [2]파일 다운로드1
4839오세운6/2/201711329로그인폼 만들기 [1]
4838후배5/29/201712037PDF Reader 라이브러리.. [3]
4837KDP5/29/201711545c++ to C# 컨버팅 문의 [2]
4836popo5/26/201714659리플렉션 성능 관련 질문 드립니다. [2]
4835guest5/25/201710457wpf Canvas 질문드립니다. [1]
4834부탁드립...5/19/201711353익스체인지 서버 구동중 인증서를 받는 과정에서오류가 납니다 [1]
4833안종윤5/18/201711757winform을 Web Browser에 붙일 수 있는지요? [1]
4832guest5/17/201711220c# UDP socket예제 실행방법 [3]
4831guest5/15/201713599WPF .net 3.5에서 TextBox 한글 문제 [3]
4830초보자5/7/201718468프로그램 비정상 종료 메시지 창 없애는 방법 [4]
4829윤현수4/26/201714856System.Text.Encoding 질문 [1]
... 31  32  33  34  35  36  37  38  39  [40]  41  42  43  44  45  ...