Microsoft MVP성태의 닷넷 이야기
Linq Entites 에서 string[]에 담긴 데이터를 제외하는 방법 문의 [링크 복사], [링크+제목 복사],
조회: 10485
글쓴 사람
권용완 (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]

... 91  [92]  93  94  95  96  97 
NoWriterDateCnt.TitleFile(s)
157이용휘4/20/20059319w3ip를 통해서 윈도우 미디어 화을을 올려놓을 서버..
158정성태4/20/20059743    답변글 [답변]: w3ip를 통해서 윈도우 미디어 화을을 올려놓을 서버..
155최성우4/18/200511395[질문(--),(__)]BHO로 자동 로그인 기능 구현.. 패스워드를 읽어오지를 못합니다.
156정성태4/19/200510091    답변글 [답변]: [질문(--),(__)]BHO로 자동 로그인 기능 구현.. 패스워드를 읽어오지를 못합니다.
161최성우4/21/200511186        답변글 [답변]: [답변]: [질문(--),(__)]BHO로 자동 로그인 기능 구현.. 패스워드를 읽어오지를 못합니다.
164정성태4/22/200510002            답변글 [답변]: [답변]: [답변]: [질문(--),(__)]BHO로 자동 로그인 기능 구현.. 패스워드를 읽어오지를 못합니다.
176최성우5/3/200510353                답변글 [답변]: [답변]: [답변]: [답변]: [질문(--),(__)]BHO로 자동 로그인 기능 구현.. 패스워드를 읽어오지를 못합니다.
146안연준4/14/200511073컴포넌트 안에 컴포넌트 삽입? 헐 ! -_-;;
147정성태4/14/20059953    답변글 [답변]: 컴포넌트 안에 컴포넌트 삽입? 헐 ! -_-;;
148안연준4/15/200510309        답변글 [답변]: [답변]: 컴포넌트 안에 컴포넌트 삽입? 헐 ! -_-;; [2]
142김용국4/13/200510112SmartClient 방식에서 이미지(바이너리)파일을 DataBased에 저장하기위한 방안에 대한 문의
143정성태4/14/20059754    답변글 [답변]: SmartClient 방식에서 이미지(바이너리)파일을 DataBased에 저장하기위한 방안에 대한 문의
141김종욱4/12/200510219웹하드 시스템을 ACTIVEX 로 짜고 있습니다
144정성태4/14/20059765    답변글 [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다
149김종욱4/15/20059658        답변글 [답변]: [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다 [1]
150정성태4/15/20059831            답변글 [답변]: [답변]: [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다 [1]
151김종욱4/16/200510125                답변글 [답변]: [답변]: [답변]: [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다
152정성태4/16/20059929                    답변글 [답변]: [답변]: [답변]: [답변]: [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다
153김종욱4/18/200511655                        답변글 [답변]: [답변]: [답변]: [답변]: [답변]: [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다
154정성태4/18/200510911                            답변글 [답변]: [답변]: [답변]: [답변]: [답변]: [답변]: [답변]: 웹하드 시스템을 ACTIVEX 로 짜고 있습니다 [3]
140안연준4/11/20059657Smart Client 에서 오프라인 글 중...의문점
145정성태4/14/20059508    답변글 [답변]: Smart Client 에서 오프라인 글 중...의문점 [1]
134김용국4/6/200514117c# .Net 에 대한 문의좀 ^^ [WinForm 에서 UserControl로 작성된 폼을 호출하려는데....]
135정성태4/6/200512189    답변글 [답변]: c# .Net 에 대한 문의좀 ^^ [WinForm 에서 UserControl로 작성된 폼을 호출하려는데....]
136김용국4/6/200510962        답변글 [답변]: [답변]: c# .Net 에 대한 문의좀 ^^ [WinForm 에서 UserControl로 작성된 폼을 호출하려는데....]
137정성태4/7/200510129            답변글 [답변]: [답변]: [답변]: c# .Net 에 대한 문의좀 ^^ [WinForm 에서 UserControl로 작성된 폼을 호출하려는데....]
... 91  [92]  93  94  95  96  97