Microsoft MVP성태의 닷넷 이야기
Linq Entites 에서 string[]에 담긴 데이터를 제외하는 방법 문의 [링크 복사], [링크+제목 복사],
조회: 10561
글쓴 사람
권용완 (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)
54차광석8/26/200411522잘 지내시죠?
55정성태8/27/200410635    답변글 [답변]: 잘 지내시죠?
52김명원8/3/200411439질문이요..
53정성태8/19/200411296    답변글 [답변]: 질문이요..
50김상표7/5/200411092질문요...
51정성태7/6/200410926    답변글 [답변]: 질문요...
45송야5/29/200411067웹페이지 자동로그인..
46정성태5/31/200411945    답변글 [답변]: 웹페이지 자동로그인..
44반데라이차5/26/200411122안녕하세요~저 오크에요~~^^* [1]
43이윤복4/22/20049926윤보기 입니다.
48정성태5/31/200411311    답변글 [답변]: 윤보기 입니다.
40김대웅2/26/200412307메일 드렸는데.. 읽어보셨는지 모르겠네요.. 많이 바쁘신것 같아요..
41정성태2/29/200411282    답변글 [답변]: 메일 드렸는데.. 읽어보셨는지 모르겠네요.. 많이 바쁘신것 같아요..
42정성태3/6/200412490    답변글 [답변]: 메일로 답변을 드렸는데. 메일이 자꾸 반송되네요. 여기서 답변드립니다.
38문우영1/19/200410943ㅋㅋ 한글 아이디도 되는군요.!!
39정성태1/26/200411556    답변글 [답변]: 다행이네요. ^^;
33신종화1/9/200412349성태님 오랬만이군요 ^^ 새해복 많이 받으세요
35정성태1/17/200410529    답변글 [답변]: 성태님 오랬만이군요 ^^ 새해복 많이 받으세요
32김기영1/5/200411255질문인데요... 웹브라우저로 text를 전송할 수 있을까요??
34정성태1/17/200410808    답변글 [답변]: 질문인데요... 웹브라우저로 text를 전송할 수 있을까요??
28박소연10/30/200314737c언어를 이용한 가계부 프로그램
31정성태12/17/200316168    답변글 [답변]: c언어를 이용한 가계부 프로그램
27임영택9/17/200311329atl com에서 Window Handle 구하고 싶은데(바쁘시더라도 꼭 답변 해주세요!!)
30정성태12/17/200311736    답변글 [답변]: atl com에서 Window Handle 구하고 싶은데(바쁘시더라도 꼭 답변 해주세요!!)
26임영택9/15/200310827IE에서 submit 버튼을 누를때 발생하는 이벤트를 받을수 있나요?
29정성태12/17/200310837    답변글 [답변]: IE에서 submit 버튼을 누를때 발생하는 이벤트를 받을수 있나요?
... 91  92  93  94  95  [96]  97