<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>필터링 Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<atom:link href="https://lycos7560.com/tag/%ed%95%84%ed%84%b0%eb%a7%81/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>생각의 흐름을 타고 다니며 만드는 블로그</description>
	<lastBuildDate>Wed, 30 Jul 2025 07:13:31 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://lycos7560.com/wp-content/uploads/2022/11/cropped-cropped-cropped-log-1-150x150-1-80x80.png</url>
	<title>필터링 Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Swagger/OpenAPI for .NET</title>
		<link>https://lycos7560.com/c/asp-net/swagger-openapi-for-net/40167/</link>
					<comments>https://lycos7560.com/c/asp-net/swagger-openapi-for-net/40167/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Wed, 18 Jun 2025 07:06:11 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET6]]></category>
		<category><![CDATA[.NET7]]></category>
		<category><![CDATA[.NET8]]></category>
		<category><![CDATA[Accept헤더]]></category>
		<category><![CDATA[API가이드라인]]></category>
		<category><![CDATA[API계약]]></category>
		<category><![CDATA[API명세]]></category>
		<category><![CDATA[API문서화]]></category>
		<category><![CDATA[API버전관리]]></category>
		<category><![CDATA[API설계]]></category>
		<category><![CDATA[API테스트]]></category>
		<category><![CDATA[Application Insights]]></category>
		<category><![CDATA[appsettings]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[Bearer토큰]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Content-Type]]></category>
		<category><![CDATA[CORS]]></category>
		<category><![CDATA[DTO패턴]]></category>
		<category><![CDATA[FluentValidation]]></category>
		<category><![CDATA[FromBody]]></category>
		<category><![CDATA[FromQuery]]></category>
		<category><![CDATA[HTTP메서드]]></category>
		<category><![CDATA[HTTP상태코드]]></category>
		<category><![CDATA[Identity]]></category>
		<category><![CDATA[IdentityServer]]></category>
		<category><![CDATA[Interactive Documentation]]></category>
		<category><![CDATA[JSON Schema]]></category>
		<category><![CDATA[JSON직렬화]]></category>
		<category><![CDATA[JWT인증]]></category>
		<category><![CDATA[NuGet패키지]]></category>
		<category><![CDATA[OAuth2]]></category>
		<category><![CDATA[OpenAPI]]></category>
		<category><![CDATA[OpenAPI Specification]]></category>
		<category><![CDATA[ProducesResponseType]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[REST API]]></category>
		<category><![CDATA[RESTful설계]]></category>
		<category><![CDATA[Swagger]]></category>
		<category><![CDATA[SwaggerGen]]></category>
		<category><![CDATA[SwaggerUI]]></category>
		<category><![CDATA[Swashbuckle]]></category>
		<category><![CDATA[XML주석]]></category>
		<category><![CDATA[개발도구]]></category>
		<category><![CDATA[개발생산성]]></category>
		<category><![CDATA[개발환경]]></category>
		<category><![CDATA[검색]]></category>
		<category><![CDATA[결과필터]]></category>
		<category><![CDATA[구성관리]]></category>
		<category><![CDATA[권한부여]]></category>
		<category><![CDATA[글로벌필터]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[네이밍컨벤션]]></category>
		<category><![CDATA[단위테스트]]></category>
		<category><![CDATA[데이터어노테이션]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[라우팅]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[리플렉션]]></category>
		<category><![CDATA[린팅]]></category>
		<category><![CDATA[메타데이터추출]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모델바인딩]]></category>
		<category><![CDATA[문서화자동화]]></category>
		<category><![CDATA[미들웨어]]></category>
		<category><![CDATA[미들웨어파이프라인]]></category>
		<category><![CDATA[백엔드개발]]></category>
		<category><![CDATA[보안설정]]></category>
		<category><![CDATA[사용량추적]]></category>
		<category><![CDATA[상태코드]]></category>
		<category><![CDATA[서비스등록]]></category>
		<category><![CDATA[성능분석]]></category>
		<category><![CDATA[성능최적화]]></category>
		<category><![CDATA[순환참조]]></category>
		<category><![CDATA[스키마생성]]></category>
		<category><![CDATA[스키마필터]]></category>
		<category><![CDATA[스테이징환경]]></category>
		<category><![CDATA[액션메서드]]></category>
		<category><![CDATA[액션필터]]></category>
		<category><![CDATA[에러핸들링]]></category>
		<category><![CDATA[역할기반접근제어]]></category>
		<category><![CDATA[예외처리]]></category>
		<category><![CDATA[오류처리]]></category>
		<category><![CDATA[요청응답]]></category>
		<category><![CDATA[웹API]]></category>
		<category><![CDATA[유효성검사]]></category>
		<category><![CDATA[응답타입]]></category>
		<category><![CDATA[의존성주입]]></category>
		<category><![CDATA[인증통합]]></category>
		<category><![CDATA[인증필터]]></category>
		<category><![CDATA[자동문서화]]></category>
		<category><![CDATA[자동화배포]]></category>
		<category><![CDATA[정렬]]></category>
		<category><![CDATA[정적분석]]></category>
		<category><![CDATA[제네릭타입]]></category>
		<category><![CDATA[지속적통합]]></category>
		<category><![CDATA[컨트롤러]]></category>
		<category><![CDATA[코드리뷰]]></category>
		<category><![CDATA[코드퍼스트]]></category>
		<category><![CDATA[코드품질]]></category>
		<category><![CDATA[클레임기반인증]]></category>
		<category><![CDATA[타입안전성]]></category>
		<category><![CDATA[텔레메트리]]></category>
		<category><![CDATA[통합테스트]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[팀협업]]></category>
		<category><![CDATA[파라미터바인딩]]></category>
		<category><![CDATA[페이징]]></category>
		<category><![CDATA[프로덕션배포]]></category>
		<category><![CDATA[프론트엔드백엔드]]></category>
		<category><![CDATA[필터링]]></category>
		<category><![CDATA[환경변수]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40167</guid>

					<description><![CDATA[<p>📖 Swagger(스웨거)란 무엇인가? Swagger는 현재 OpenAPI Specification (OAS)라는 이름으로 표준화된 RESTful API 명세 및 문서화 도구입니다. 2015년 SmartBear Software에서 OpenAPI Initiative에 기증한 후, 현재는 Linux Foundation 산하에서 관리되고 있습니다. 핵심 개념 🎯 Swagger가 필요한 이유 1. 개발 생산성 향상 2. 팀 협업 효율성 3. 운영 및 테스트 📦 Swashbuckle.AspNetCore 아키텍처 Swashbuckle.AspNetCore는 .NET에서 Swagger/OpenAPI를 구현하는 가장 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/asp-net/swagger-openapi-for-net/40167/">Swagger/OpenAPI for .NET</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-aee946f9      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#swagger스웨거란-무엇인가" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d6.png" alt="📖" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swagger(스웨거)란 무엇인가?</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#핵심-개념" class="uagb-toc-link__trigger">핵심 개념</a></li></ul></li><li class="uagb-toc__list"><a href="#swagger가-필요한-이유" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swagger가 필요한 이유</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-개발-생산성-향상" class="uagb-toc-link__trigger">1. 개발 생산성 향상</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-팀-협업-효율성" class="uagb-toc-link__trigger">2. 팀 협업 효율성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-운영-및-테스트" class="uagb-toc-link__trigger">3. 운영 및 테스트</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#swashbuckleaspnetcore-아키텍처" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swashbuckle.AspNetCore 아키텍처</a><li class="uagb-toc__list"><a href="#net-6-프로젝트에서-swagger-구성" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> .NET 6+ 프로젝트에서 Swagger 구성</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-패키지-설치" class="uagb-toc-link__trigger">1. 패키지 설치</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-기본-구성-programcs" class="uagb-toc-link__trigger">2. 기본 구성 (Program.cs)</a></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#swaggergen의-동작-원리" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> SwaggerGen의 동작 원리</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#생성되는-openapi-문서-예시" class="uagb-toc-link__trigger">생성되는 OpenAPI 문서 예시</a></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#swagger-ui-고급-활용" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c4.png" alt="📄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swagger UI 고급 활용</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#주요-기능" class="uagb-toc-link__trigger">주요 기능</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#커스터마이징-옵션" class="uagb-toc-link__trigger">커스터마이징 옵션</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#실무-필수-확장-기능" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e9.png" alt="🧩" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 실무 필수 확장 기능</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-xml-주석-통합" class="uagb-toc-link__trigger">1. XML 주석 통합</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-jwt-bearer-인증-통합" class="uagb-toc-link__trigger">2. JWT Bearer 인증 통합</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-api-버전-관리" class="uagb-toc-link__trigger">3. API 버전 관리</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-사용자-정의-스키마-필터" class="uagb-toc-link__trigger">4. 사용자 정의 스키마 필터</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#성능-최적화-및-모범-사례" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 성능 최적화 및 모범 사례</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-프로덕션-환경-고려사항" class="uagb-toc-link__trigger">1. 프로덕션 환경 고려사항</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-대용량-api-문서-최적화" class="uagb-toc-link__trigger">2. 대용량 API 문서 최적화</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-보안-강화" class="uagb-toc-link__trigger">3. 보안 강화</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#트러블슈팅-가이드" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 트러블슈팅 가이드</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#일반적인-문제와-해결책" class="uagb-toc-link__trigger">일반적인 문제와 해결책</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#모니터링-및-분석" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c8.png" alt="📈" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 모니터링 및 분석</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#application-insights-통합" class="uagb-toc-link__trigger">Application Insights 통합</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#요약-및-베스트-프랙티스" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 요약 및 베스트 프랙티스</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#핵심-도구-정리" class="uagb-toc-link__trigger">핵심 도구 정리</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#개발팀을-위한-권장사항" class="uagb-toc-link__trigger">개발팀을 위한 권장사항</a></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d6.png" alt="📖" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swagger(스웨거)란 무엇인가?</h2>



<p><strong>Swagger</strong>는 현재 OpenAPI Specification (OAS)라는 이름으로 표준화된 <strong>RESTful API 명세 및 문서화 도구</strong>입니다. </p>



<p>2015년 SmartBear Software에서 OpenAPI Initiative에 기증한 후, 현재는 Linux Foundation 산하에서 관리되고 있습니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">핵심 개념</h3>



<ul class="wp-block-list">
<li><strong>API 명세의 표준화</strong>: REST API의 엔드포인트, 파라미터, 응답 구조를 JSON/YAML 형식으로 정의</li>



<li><strong>Code-First 접근</strong>: 소스코드로부터 API 문서를 자동 생성하여 문서와 구현 간 불일치 방지</li>



<li><strong>Interactive Documentation</strong>: 브라우저에서 직접 API를 테스트할 수 있는 UI 제공</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swagger가 필요한 이유</h2>



<h3 class="wp-block-heading">1. 개발 생산성 향상</h3>



<ul class="wp-block-list">
<li><strong>자동 문서화</strong>: 수동으로 API 문서를 작성하고 유지보수하는 비용 절약</li>



<li><strong>실시간 동기화</strong>: 코드 변경 시 문서가 자동으로 업데이트</li>



<li><strong>타입 안전성</strong>: .NET의 강타입 시스템을 활용한 정확한 스키마 생성</li>
</ul>



<h3 class="wp-block-heading">2. 팀 협업 효율성</h3>



<ul class="wp-block-list">
<li><strong>프론트엔드-백엔드 협업</strong>: 명확한 API 계약 정의를 통한 병렬 개발 지원</li>



<li><strong>API 계약 테스트</strong>: 구현 전 API 설계 검증 가능</li>



<li><strong>버전 관리</strong>: API 변경사항 추적 및 하위 호환성 관리</li>
</ul>



<h3 class="wp-block-heading">3. 운영 및 테스트</h3>



<ul class="wp-block-list">
<li><strong>통합 테스트</strong>: CI/CD 파이프라인에서 자동화된 API 테스트</li>



<li><strong>모니터링</strong>: API 사용 패턴 분석 및 성능 모니터링 기반 제공</li>
</ul>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swashbuckle.AspNetCore 아키텍처</h2>



<p>Swashbuckle.AspNetCore는 .NET에서 Swagger/OpenAPI를 구현하는 가장 널리 사용되는 라이브러리입니다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>패키지</th><th>역할</th><th>주요 기능</th></tr></thead><tbody><tr><td><code>Swashbuckle.AspNetCore.Swagger</code></td><td>OpenAPI 문서 생성 엔진</td><td>JSON/YAML 형식의 OpenAPI 명세 생성</td></tr><tr><td><code>Swashbuckle.AspNetCore.SwaggerGen</code></td><td>코드 분석 및 메타데이터 추출</td><td>리플렉션을 통한 컨트롤러/액션 분석</td></tr><tr><td><code>Swashbuckle.AspNetCore.SwaggerUI</code></td><td>웹 UI 렌더링</td><td>인터랙티브한 API 문서 및 테스트 인터페이스</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> .NET 6+ 프로젝트에서 Swagger 구성</h2>



<h3 class="wp-block-heading">1. 패키지 설치</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Package Manager Console
Install-Package Swashbuckle.AspNetCore

# .NET CLI
dotnet add package Swashbuckle.AspNetCore
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. 기본 구성 (Program.cs)</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var builder = WebApplication.CreateBuilder(args);

// 컨트롤러 서비스 등록
builder.Services.AddControllers();

// Swagger 서비스 등록
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "My API",
        Description = "ASP.NET Core Web API for demonstration",
        Contact = new OpenApiContact
        {
            Name = "Developer Name",
            Email = "developer@example.com"
        }
    });
});

var app = builder.Build();

// 개발 환경에서만 Swagger 활성화
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        options.RoutePrefix = string.Empty; // 루트 경로에서 Swagger UI 제공
    });
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> SwaggerGen의 동작 원리</h2>



<p>SwaggerGen은 다음과 같은 과정을 통해 OpenAPI 문서를 생성합니다:</p>



<ol class="wp-block-list">
<li><strong>어셈블리 스캔</strong>: 등록된 컨트롤러와 액션 메서드 탐색</li>



<li><strong>메타데이터 추출</strong>: 라우트, HTTP 메서드, 파라미터, 반환 타입 분석</li>



<li><strong>스키마 생성</strong>: .NET 타입을 JSON Schema로 변환</li>



<li><strong>문서 조합</strong>: OpenAPI 3.0 사양에 맞는 JSON 문서 생성</li>
</ol>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">생성되는 OpenAPI 문서 예시</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
  "openapi": "3.0.1",
  "info": {
    "title": "My API",
    "version": "v1"
  },
  "paths": {
    "/api/products": {
      "get": {
        "tags": ["Products"],
        "summary": "제품 목록 조회",
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Product"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Product": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "format": "int32" },
          "name": { "type": "string", "nullable": true }
        }
      }
    }
  }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1378" height="1299" src="https://lycos7560.com/wp-content/uploads/2025/07/image-19.png" alt="" class="wp-image-40168" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-19.png 1378w, https://lycos7560.com/wp-content/uploads/2025/07/image-19-300x283.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-19-768x724.png 768w" sizes="(max-width: 1378px) 100vw, 1378px" /></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c4.png" alt="📄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Swagger UI 고급 활용</h2>



<p>Swagger UI는 생성된 OpenAPI 문서를 기반으로 다음 기능을 제공합니다:</p>



<h3 class="wp-block-heading">주요 기능</h3>



<ul class="wp-block-list">
<li><strong>HTTP 메서드별 분류</strong>: GET, POST, PUT, DELETE 등 시각적 구분</li>



<li><strong>스키마 검증</strong>: 요청/응답 데이터 구조 실시간 검증</li>



<li><strong>Try it Out</strong>: 브라우저에서 직접 API 호출 및 결과 확인</li>



<li><strong>모델 정의</strong>: 복잡한 객체 구조의 시각적 표현</li>



<li><strong>인증 통합</strong>: 다양한 인증 방식 지원 (Bearer, API Key 등)</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">커스터마이징 옵션</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    options.DocumentTitle = "My API Documentation";
    options.DefaultModelsExpandDepth(2);
    options.DefaultModelRendering(ModelRendering.Model);
    options.DisplayRequestDuration();
    options.EnableDeepLinking();
    options.EnableFilter();
    options.ShowExtensions();
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e9.png" alt="🧩" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 실무 필수 확장 기능</h2>



<h3 class="wp-block-heading">1. XML 주석 통합</h3>



<p>프로젝트 파일 설정:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;PropertyGroup>
  &lt;GenerateDocumentationFile>true&lt;/GenerateDocumentationFile>
  &lt;NoWarn>$(NoWarn);1591&lt;/NoWarn>
&lt;/PropertyGroup>
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Program.cs 구성:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">builder.Services.AddSwaggerGen(options =>
{
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
    
    // 상속된 XML 주석 포함
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "MyModels.xml"));
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>컨트롤러 예시:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/// &lt;summary>
/// 제품 관리 API
/// &lt;/summary>
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    /// &lt;summary>
    /// 제품 목록을 조회합니다.
    /// &lt;/summary>
    /// &lt;param name="pageSize">페이지당 항목 수 (기본값: 10)&lt;/param>
    /// &lt;returns>제품 목록&lt;/returns>
    /// &lt;response code="200">성공적으로 조회됨&lt;/response>
    /// &lt;response code="400">잘못된 요청 파라미터&lt;/response>
    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable&lt;Product>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task&lt;ActionResult&lt;IEnumerable&lt;Product>>> GetProducts(
        [FromQuery] int pageSize = 10)
    {
        // 구현 로직
    }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. JWT Bearer 인증 통합</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">builder.Services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Name = "Authorization",
        Type = SecuritySchemeType.Http,
        Scheme = "Bearer",
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\""
    });

    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty&lt;string>()
        }
    });
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. API 버전 관리</h3>



<p>패키지 설치:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dotnet add package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>구성:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ApiVersionReader = ApiVersionReader.Combine(
        new UrlSegmentApiVersionReader(),
        new HeaderApiVersionReader("X-Version"),
        new MediaTypeApiVersionReader("ver"));
});

builder.Services.AddVersionedApiExplorer(setup =>
{
    setup.GroupNameFormat = "'v'VVV";
    setup.SubstituteApiVersionInUrl = true;
});

builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions&lt;ConfigureSwaggerOptions>();
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4. 사용자 정의 스키마 필터</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public class EnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            schema.Enum.Clear();
            Enum.GetNames(context.Type)
                .ToList()
                .ForEach(name => schema.Enum.Add(new OpenApiString(name)));
        }
    }
}

// 등록
builder.Services.AddSwaggerGen(options =>
{
    options.SchemaFilter&lt;EnumSchemaFilter>();
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 성능 최적화 및 모범 사례</h2>



<h3 class="wp-block-heading">1. 프로덕션 환경 고려사항</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 조건부 Swagger 활성화
if (app.Environment.IsDevelopment() || app.Environment.IsStaging())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

// 또는 구성 기반 활성화
if (builder.Configuration.GetValue&lt;bool>("EnableSwagger"))
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
</pre>



<h3 class="wp-block-heading">2. 대용량 API 문서 최적화</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">builder.Services.AddSwaggerGen(options =>
{
    // 불필요한 스키마 제외
    options.SchemaFilter&lt;ExcludeInternalTypesFilter>();
    
    // 문서 압축
    options.EnableAnnotations();
    
    // 메모리 사용량 최적화
    options.UseAllOfToExtendReferenceSchemas();
    options.UseOneOfForPolymorphism();
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. 보안 강화</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseSwagger(options =>
{
    // JSON 문서 접근 제한
    options.PreSerializeFilters.Add((swagger, httpReq) =>
    {
        if (!httpReq.Headers.ContainsKey("X-API-Key"))
        {
            throw new UnauthorizedAccessException();
        }
    });
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 트러블슈팅 가이드</h2>



<h3 class="wp-block-heading">일반적인 문제와 해결책</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>문제</th><th>원인</th><th>해결방법</th></tr></thead><tbody><tr><td>XML 주석이 표시되지 않음</td><td>XML 파일 경로 오류</td><td>빌드 출력 디렉토리 확인 및 경로 수정</td></tr><tr><td>복잡한 제네릭 타입 오류</td><td>스키마 생성 실패</td><td>사용자 정의 SchemaFilter 구현</td></tr><tr><td>순환 참조 오류</td><td>모델 간 순환 의존성</td><td>JsonIgnore 또는 DTO 패턴 적용</td></tr><tr><td>인증 테스트 실패</td><td>CORS 또는 인증 설정 문제</td><td>CORS 정책 및 인증 미들웨어 순서 확인</td></tr></tbody></table></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c8.png" alt="📈" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 모니터링 및 분석</h2>



<h3 class="wp-block-heading">Application Insights 통합</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">builder.Services.AddApplicationInsightsTelemetry();

// Swagger 사용량 추적
app.UseSwagger(options =>
{
    options.PreSerializeFilters.Add((swagger, httpReq) =>
    {
        var telemetryClient = httpReq.HttpContext.RequestServices
            .GetRequiredService&lt;TelemetryClient>();
        telemetryClient.TrackEvent("SwaggerAccessed");
    });
});
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 요약 및 베스트 프랙티스</h2>



<h3 class="wp-block-heading">핵심 도구 정리</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>도구/개념</th><th>설명</th><th>권장 사용 시나리오</th></tr></thead><tbody><tr><td><strong>OpenAPI/Swagger</strong></td><td>REST API 명세 표준</td><td>모든 REST API 프로젝트</td></tr><tr><td><strong>Swashbuckle.AspNetCore</strong></td><td>.NET용 Swagger 구현체</td><td>ASP.NET Core 웹 API</td></tr><tr><td><strong>Swagger UI</strong></td><td>인터랙티브 API 문서</td><td>개발 및 테스트 환경</td></tr><tr><td><strong>SwaggerGen</strong></td><td>코드 기반 문서 생성기</td><td>자동화된 문서 관리</td></tr></tbody></table></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">개발팀을 위한 권장사항</h3>



<ol class="wp-block-list">
<li><strong>개발 초기</strong>부터 Swagger 도입하여 API 설계 단계에서 문서화</li>



<li><strong>XML 주석</strong>을 활용한 상세한 API 설명 작성</li>



<li><strong>DTO 패턴</strong> 적용으로 명확한 API 계약 정의</li>



<li><strong>버전 관리</strong> 전략 수립으로 하위 호환성 보장</li>



<li><strong>보안 설정</strong> 통합으로 실제 운영 환경과 일치하는 테스트 환경 구축</li>



<li><strong>CI/CD 파이프라인</strong>에 OpenAPI 스펙 검증 단계 포함</li>
</ol>



<p>이러한 접근을 통해 Swagger/OpenAPI는 단순한 문서화 도구를 넘어서 API 개발 생명주기 전반을 지원하는 핵심 인프라가 될 수 있습니다.</p>
<p>The post <a href="https://lycos7560.com/c/asp-net/swagger-openapi-for-net/40167/">Swagger/OpenAPI for .NET</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/asp-net/swagger-openapi-for-net/40167/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>LINQ – 이것이 C# 이다.</title>
		<link>https://lycos7560.com/c/linq-programming-c/3281/</link>
					<comments>https://lycos7560.com/c/linq-programming-c/3281/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Sun, 11 Dec 2022 15:05:04 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[linq]]></category>
		<category><![CDATA[method]]></category>
		<category><![CDATA[orderby]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[데이터 추출]]></category>
		<category><![CDATA[링큐]]></category>
		<category><![CDATA[생성]]></category>
		<category><![CDATA[수량 연산]]></category>
		<category><![CDATA[이것이C#이다]]></category>
		<category><![CDATA[정렬]]></category>
		<category><![CDATA[집합]]></category>
		<category><![CDATA[쿼리식]]></category>
		<category><![CDATA[필터링]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=3281</guid>

					<description><![CDATA[<p>이것이 C#이다의 linq 파트를 요약하여 정리한 글입니다. (This is a summary of the linq part of C#ida.)</p>
<p>The post <a href="https://lycos7560.com/c/linq-programming-c/3281/">LINQ – 이것이 C# 이다.</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5698326622209671"
     crossorigin="anonymous"></script>
<!-- HorizontalAD -->
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-5698326622209671"
     data-ad-slot="6908948342"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h1 class="wp-block-heading">LINQ – 이것이 C# 이다.</h1>



<p class="has-medium-font-size"><strong>쿼리식 연산자의 종류</strong></p>



<p class="has-medium-font-size">&#8211; from</p>



<p class="has-medium-font-size">&#8211; where</p>



<p class="has-medium-font-size">&#8211; orderby</p>



<p class="has-medium-font-size">&#8211; select</p>



<p class="has-medium-font-size">&#8211; group by</p>



<p class="has-medium-font-size">&#8211; join</p>



<p class="has-medium-font-size"><strong>&#8211; 여러 개의 데이터 원본에 질의</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211;&nbsp; L I N Q&nbsp; &#8211;</strong></h2>



<p class="has-medium-font-size">LINQ(Language INtegrated Query) 는&nbsp;<strong>컬렉션을 편리하게 다루기 위한 목적으로 만들어진 질의(Query) 언어</strong>입니다.</p>



<p class="has-medium-font-size">질의란? 무엇인가에 대하여 물어본다는 뜻인데 데이터 질의란&nbsp;데이터에 대해 물어본다는 말입니다.</p>



<div style="height:51px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">기본적인 질문은 아래와 같습니다.</p>



<p class="has-medium-font-size">from :&nbsp;어떤 데이터를 집합에서 찾을 것인가?</p>



<p class="has-medium-font-size">where :&nbsp;어떤 값의 데이터를 찾을 것인가?</p>



<p class="has-medium-font-size">orderby : 어떤 기준으로&nbsp;정렬할 것인가?</p>



<p class="has-medium-font-size">select :&nbsp;어떤 항목을 추출할 것인가?</p>



<div style="height:56px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Profile
    {
    
        public string Name { get; set; }
        public int Height { get; set; }

    }
    class MainApp
    {

        static void Main(string[] args)
        {
            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                                    };
        }

    }</pre>



<div style="height:73px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">위의 예시에서 키가 170 이상인 데이터만 찾아서 새 컬렉션으로 추가한다고 한다면?</p>



<div style="height:53px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Collections.Generic;

namespace ConsoleApp2
{

    class Profile
    {
    
        public string Name { get; set; }
        public int Height { get; set; }

    }
    class MainApp
    {

        static void Main(string[] args)
        {
            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             // ...
                                    };

            List&lt;Profile> profiles = new List&lt;Profile>();
            foreach (Profile data in arrProfiles )
            {
                if (data.Height >= 170)
                {
                    profiles.Add(data);
                }
            }

            foreach (Profile data in profiles)
            {
                Console.WriteLine("{0} , {1}", data.Name , data.Height);

            }

        }
        
    }
}</pre>



<div style="height:52px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="578" height="285" src="https://lycos7560.com/wp-content/uploads/image-623.png" alt="" class="wp-image-3282" srcset="https://lycos7560.com/wp-content/uploads/image-623.png 578w, https://lycos7560.com/wp-content/uploads/image-623-300x148.png 300w" sizes="(max-width: 578px) 100vw, 578px" /></figure>



<div style="height:74px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">코드에 잘못된 부분은 없으나&nbsp;<strong>LINQ를 모르는 프로그래머</strong>의 코드 라는 평을 듣습니다.</p>



<p class="has-medium-font-size">다음예제는 LINQ를 사용한 예제입니다.</p>



<div style="height:39px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

    }
    
    class MainApp
    {

        static void Main(string[] args)
        {
        
            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };


			//  LINQ
            var profiles = from profile in arrProfiles
                           where profile.Height >= 170
                           orderby profile.Height ascending
                           select profile;


            foreach (Profile data in profiles)
            {
                Console.WriteLine("{0} , {1}", data.Name, data.Height);
            }

        }
    }
}</pre>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="641" height="289" src="https://lycos7560.com/wp-content/uploads/image-624.png" alt="" class="wp-image-3283" srcset="https://lycos7560.com/wp-content/uploads/image-624.png 641w, https://lycos7560.com/wp-content/uploads/image-624-300x135.png 300w" sizes="(max-width: 641px) 100vw, 641px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211; from &#8211;&nbsp;</strong></h2>



<p class="has-medium-font-size">모든 쿼리식(Query Expression)은 반드시&nbsp;<strong>from절</strong>로 시작합니다.</p>



<p class="has-medium-font-size">쿼리식의 대상이 될&nbsp;<strong>데이터 원본(Data Source)</strong>과&nbsp;데이터 원본 안에 들어 있는 각 요소 데이터를 나타내는</p>



<p class="has-medium-font-size"><strong>범위 변수(Range Variable) (= 쿼리 변수(Query Variable))&nbsp;</strong>를&nbsp; from 절에서 지정합니다.</p>



<div style="height:45px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size"><strong>데이터 원본</strong>은 아무 형식이나 사용할 수 없고,&nbsp;<strong>IEnumerable&lt;T&gt; 인터페이스를 상속하는 형식</strong>만 가능합니다.</p>



<p class="has-medium-font-size"><a href="https://learn.microsoft.com/ko-kr/dotnet/api/system.collections.generic.ienumerable-1?view=net-6.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/system.collections.generic.ienumerable-1?view=net-6.0</a></p>



<p class="has-medium-font-size"><strong>배열</strong>&nbsp;또는&nbsp;<strong>컬렉션 객체</strong>들은 이를 상속하므로 모드 from절의 데이터 원본으로 사용할 수 있습니다.</p>



<div style="height:45px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size"><strong>범위변수</strong>는 foreach 문의 반복변수와 비슷합니다.</p>



<p class="has-medium-font-size">단. 반복변수는 데이터 원본으로부터 데이터를 담아내지만, 범위 변수는 실제로 데이터를 담지않습니다.</p>



<p class="has-medium-font-size">그래서 쿼리식 외부에서 선언된 변수에 범위 변수의 데이터를 복사해 넣는다든가 하는 일은 할 수 없습니다.</p>



<p class="has-medium-font-size">범위변수는 오로지 LINQ 질의 안에서만 통용됩니다.</p>



<div style="height:44px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class MainApp
    {

        static void Main(string[] args)
        {
            int[] intArr = { 10, 41, 7, 67, 3, 13, 15, 25, 76, 89, 44, 33, 22, 1 };

            var evenNumber = from data in intArr
                             where data % 2 == 0
                             orderby data descending 
                             select data;

            foreach (int data1 in evenNumber)
            {
                Console.Write(" 짝수 : {0}  ", data1);
            }

        }
    }
}</pre>



<div style="height:44px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211; where &#8211;&nbsp;</strong></h2>



<p class="has-medium-font-size">where 은&nbsp;<strong>필터 역할</strong>(Filter)을 하는 연산자 입니다.</p>



<p class="has-medium-font-size">from 절이 데이터의 원본으로부터 뽑아낸 범위 변수가 가져야 하는 조건을 where 연산자에 인수로 입력하면</p>



<p class="has-medium-font-size">LINQ는&nbsp;<strong>해당조건에 부합하는 데이터만을 걸러냅니다.</strong>&nbsp;</p>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211; orderby &#8211;&nbsp;</strong></h2>



<p class="has-medium-font-size">orderby는 정렬을 수행하는 연산자 입니다.</p>



<p class="has-medium-font-size">위의 예제</p>



<p class="has-medium-font-size">orderby profile.Height&nbsp;<strong>ascending</strong>&nbsp; // 오름차순 정렬</p>



<p class="has-medium-font-size">orderby data&nbsp;<strong>descending</strong>&nbsp; // 내림차순 정렬</p>



<p class="has-medium-font-size">와 같이 사용합니다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211; select &#8211;&nbsp;</strong></h2>



<p class="has-medium-font-size">select 절은 최종 결과를 추출하는 쿼리식의 마침표 같은 존재입니다.</p>



<p class="has-medium-font-size">from 절에서 데이터 원본으로부터 범위 변수를 뽑아내고</p>



<p class="has-medium-font-size">where 절에서 이 범위 변수의 조건을 검사한 후</p>



<p class="has-medium-font-size">orderby 절에서 결과를 정리하고</p>



<p class="has-medium-font-size">select 문을 통하여 최종 결과를 추출해내는 것 입니다.</p>



<div style="height:37px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var profiles = from profile in arrProfiles
               where profile.Height >= 170
               orderby profile.Height
               select profile;</pre>



<div style="height:42px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">LINQ 질의 결과는 IEnumerable&lt;T&gt;로 반환되는데, 이떄 형식 매개변수T는 Select 문에 의해 결정됩니다.</p>



<p class="has-medium-font-size">위의 질의 결과는&nbsp;IEnumerable&lt;profile&gt; 형식입니다.</p>



<p class="has-medium-font-size">만약 select 문에서 profile 객체 전체가 아닌 Name 프로퍼티만 추출하면&nbsp;IEnumerable&lt;string&gt; 형식으로 컴파일 됩니다.</p>



<div style="height:39px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var profiles = from profile in arrProfiles
               where profile.Height >= 170
               orderby profile.Height ascending
               select profile.Name;


foreach (string data in profiles)
{
	Console.WriteLine("{0} ", data);
}</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">또한 select 문의 무명 형식을 이용하여 새로운 형식을 즉석에서 만들 수 있습니다.</p>



<div style="height:49px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

    }

    class MainApp
    {

        static void Main(string[] args)
        {

            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };


            //  LINQ
            var profiles = from profile in arrProfiles
                           where profile.Height >= 170
                           orderby profile.Height 
                           select new { Name = profile.Name, InchHeight = profile.Height * 0.393 };


            foreach (var data in profiles)
            {
                Console.WriteLine("{0} ", data);
            }

            Console.WriteLine(profiles.GetType());
        }
    }
}</pre>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1283" height="224" src="https://lycos7560.com/wp-content/uploads/image-627.png" alt="" class="wp-image-3286" srcset="https://lycos7560.com/wp-content/uploads/image-627.png 1283w, https://lycos7560.com/wp-content/uploads/image-627-300x52.png 300w, https://lycos7560.com/wp-content/uploads/image-627-768x134.png 768w" sizes="(max-width: 1283px) 100vw, 1283px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211;&nbsp; group by&nbsp; &#8211;</strong></h2>



<p class="has-medium-font-size">group by 문을 통하여 분류 기준에 따라 데이터를 그룹화 할 수 있습니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">group A by B into c</pre>



<div style="height:41px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">A 에서는 from 절에서 뽑아낸&nbsp;<strong>범위 변수</strong>를, B에는&nbsp;<strong>분류 기준</strong>을, C에는&nbsp;<strong>그룹 변수</strong>를 위치시키면 됩니다.</p>



<div style="height:35px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                         };</pre>



<div style="height:32px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">위의 예제를 175 미만 / 이상 으로 분류합니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var listprofiles = from profile in arrProfiles
        	   group profile by profile.Height &lt; 175 into g
            	   select new { GroupKey = g.Key, profiles = g };</pre>



<div style="height:39px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">그룹변수 g에는 height 값이 175미만인 객체는 컬레션과 175 이상인 객체의 컬렉션이 입력되고,</p>



<p class="has-medium-font-size">select 문이 추출하는 새로운 무명형식은 컬렉션의 컬렉션이 됩니다.&nbsp;</p>



<p class="has-medium-font-size">그리고 이 무명형식의 Profiles 필드는 바로 이 그룹 변수 g를 담게됩니다.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1318" height="639" src="https://lycos7560.com/wp-content/uploads/image-628.png" alt="" class="wp-image-3287" srcset="https://lycos7560.com/wp-content/uploads/image-628.png 1318w, https://lycos7560.com/wp-content/uploads/image-628-300x145.png 300w, https://lycos7560.com/wp-content/uploads/image-628-768x372.png 768w" sizes="(max-width: 1318px) 100vw, 1318px" /></figure>



<div style="height:53px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

    }

    class MainApp
    {

        static void Main(string[] args)
        {

            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };


            //  LINQ
            var listprofiles = from profile in arrProfiles
                               group profile by profile.Height &lt; 175 into g
                               select new { GroupKey = g.Key, profiles = g };

            foreach (var Group in listprofiles)
            {
                Console.WriteLine(" - 175cm 미만? : {0}", Group.GroupKey);
                foreach (var data in Group.profiles)
                {
                    Console.WriteLine("{0} :  {1}", data.Name, data.Height);
                }
            }

        }
    }
}</pre>



<div style="height:28px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="582" height="357" src="https://lycos7560.com/wp-content/uploads/image-629.png" alt="" class="wp-image-3288" srcset="https://lycos7560.com/wp-content/uploads/image-629.png 582w, https://lycos7560.com/wp-content/uploads/image-629-300x184.png 300w" sizes="(max-width: 582px) 100vw, 582px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5698326622209671"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-format="autorelaxed"
     data-ad-client="ca-pub-5698326622209671"
     data-ad-slot="4245812909"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>



<div style="height:52px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>&#8211;&nbsp; join&nbsp; &#8211;</strong></h2>



<p class="has-large-font-size"><strong>&#8211; 내부 조인</strong></p>



<p class="has-medium-font-size">내부조인(Inner) 은 교집합과 비슷합니다.</p>



<p class="has-medium-font-size">두 데이터 원본 사이에서 일치하는 데이터들만 연결한 후 반환합니다. 기준은 원본 데이터 입니다.</p>



<div style="height:38px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1315" height="913" src="https://lycos7560.com/wp-content/uploads/image-630.png" alt="" class="wp-image-3289" srcset="https://lycos7560.com/wp-content/uploads/image-630.png 1315w, https://lycos7560.com/wp-content/uploads/image-630-300x208.png 300w, https://lycos7560.com/wp-content/uploads/image-630-768x533.png 768w" sizes="(max-width: 1315px) 100vw, 1315px" /></figure>



<div style="height:44px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">내부조인을 수행 할떄 기준 데이터 원본에는 존재하지만 연결할 데이터 원본에는 존재하지 않는 데이터는 조인 결과에 포함되지 않습니다.</p>



<p class="has-medium-font-size">반대의 경우도 마찬가지 입니다.</p>



<div style="height:42px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

        public int Number { get; set; }

    }

    class Profile2
    {
        public string Star { get; set; }
        public int Number { get; set; }

    }

    class MainApp
    {

        static void Main(string[] args)
        {

            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };

            Profile2[] arr2Profiles = {
                             new Profile2() { Star = "정우성" , Number = 111 },
                             new Profile2() { Star = "김태희" , Number = 222 },
                             new Profile2() { Star = "이문세" , Number = 333 },
                             new Profile2() { Star = "하동훈" , Number = 444 },
                          // new Profile2() { Star = "홍길동" , Number = 555 },
                             new Profile2() { Star = "임꺽정" , Number = 666 }
                                    };


            //  LINQ
            var listJoin = from data1 in arrProfiles
                           join data2 in arr2Profiles on data1.Name equals data2.Star
                           select new
                           {
                               Name = data1.Name,
                               Number = data2.Number,
                               Height = data1.Height
                           };
            foreach (var data3 in listJoin)
            {
                Console.WriteLine("Name(star) : {0}, Number : {1}, Height : {2}", data3.Name, data3.Number, data3.Height);
                //  홍길동 포함 X
            }



        }
    }
}</pre>



<div style="height:44px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="735" height="281" src="https://lycos7560.com/wp-content/uploads/image-631.png" alt="" class="wp-image-3290" srcset="https://lycos7560.com/wp-content/uploads/image-631.png 735w, https://lycos7560.com/wp-content/uploads/image-631-300x115.png 300w" sizes="(max-width: 735px) 100vw, 735px" /></figure>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-large-font-size"><strong>&#8211; 외부 조인</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    }

    class Profile2
    {
        public string Star { get; set; }
        public int Number { get; set; }

    }

    class MainApp
    {

        static void Main(string[] args)
        {

            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };

            Profile2[] arr2Profiles = {
                             new Profile2() { Star = "정우성" , Number = 111 },
                             new Profile2() { Star = "김태희" , Number = 222 },
                             new Profile2() { Star = "이문세" , Number = 333 },
                             new Profile2() { Star = "하동훈" , Number = 444 },
                             new Profile2() { Star = "홍길동" },
                             new Profile2() { Star = "임꺽정" , Number = 666 }
                                    };


            //  LINQ
            var listJoin = from data1 in arrProfiles
                           join data2 in arr2Profiles on data1.Name equals data2.Star into ps
                           from data2 in ps.DefaultIfEmpty(new Profile2() { Number = 0 } )
                           select new
                           {
                               Name = data1.Name,
                               Number = data2.Number,
                               Height = data1.Height
                           };
            foreach (var data3 in listJoin)
            {
                Console.WriteLine("Name(star) : {0}, Number : {1}, Height : {2}", data3.Name, data3.Number, data3.Height);
            }

        }
    }
}</pre>



<div style="height:31px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="703" height="359" src="https://lycos7560.com/wp-content/uploads/image-632.png" alt="" class="wp-image-3291" srcset="https://lycos7560.com/wp-content/uploads/image-632.png 703w, https://lycos7560.com/wp-content/uploads/image-632-300x153.png 300w" sizes="(max-width: 703px) 100vw, 703px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<h2 class="wp-block-heading"><strong>&#8211;&nbsp; 여러 개의 데이터 원본에 질의&nbsp; &#8211;</strong></h2>



<p class="has-medium-font-size">LINQ 쿼리식은 데이터 원본에 접근하기 위해 from 절을 사용합니다.</p>



<p class="has-medium-font-size">여러 개의 데이터 원본에 접근하려면 이 from 문을 중첩해서 사용하면 됩니다.</p>



<div style="height:54px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Class
    {
        public string Name { get; set; }
        public int[] Score { get; set; }
    }

    class MainApp
    {

        static void Main(string[] args)
        {
        
            Class[] arrClass =
            {
                new Class() { Name = "연두반", Score = new int[]{ 70,24 } },
                new Class() { Name = "분홍반", Score = new int[]{ 60,45,87,72 } },
                new Class() { Name = "파랑반", Score = new int[]{ 92,30,85,94 } },
                new Class() { Name = "노랑반", Score = new int[]{ 90,88,0,10 } }
            };

            var Classes = from c in arrClass
                          from s in c.Score
                          where s &lt; 60
                          orderby s
                          select new { c.Name, Lowest = s };

            foreach (var data in Classes)
            {
                Console.WriteLine(" 낙제 : {0} ", data);
            }
        }
    }
}</pre>



<div style="height:38px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="540" height="235" src="https://lycos7560.com/wp-content/uploads/image-633.png" alt="" class="wp-image-3292" srcset="https://lycos7560.com/wp-content/uploads/image-633.png 540w, https://lycos7560.com/wp-content/uploads/image-633-300x131.png 300w" sizes="(max-width: 540px) 100vw, 540px" /></figure>



<div style="height:45px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<p class="has-medium-font-size"><a href="https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/linq/query-expression-syntax-for-standard-query-operators" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/linq/query-expression-syntax-for-standard-query-operators</a></p>



<div style="height:31px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><a href="https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/linq/query-expression-syntax-for-standard-query-operators" target="_blank" rel="noreferrer noopener"><img decoding="async" width="1536" height="321" src="https://lycos7560.com/wp-content/uploads/image-634.png" alt="" class="wp-image-3293" srcset="https://lycos7560.com/wp-content/uploads/image-634.png 1536w, https://lycos7560.com/wp-content/uploads/image-634-300x63.png 300w, https://lycos7560.com/wp-content/uploads/image-634-768x161.png 768w" sizes="(max-width: 1536px) 100vw, 1536px" /></a></figure>



<div style="height:44px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size">위의 링크는 C#에서 지원하는 11가지의 쿼리식 문법입니다.</p>



<p class="has-medium-font-size">53개의&nbsp; 표준 LINQ 연산자</p>



<p class="has-medium-font-size"><a href="https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=ljc8808&amp;logNo=220662771778" target="_blank" rel="noreferrer noopener">https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=ljc8808&amp;logNo=220662771778</a> &lt;- 출처</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table has-medium-font-size"><table><tbody><tr><td class="has-text-align-center" data-align="center"></td><td><strong>&nbsp;메소드 이름</strong></td><td><strong>&nbsp;설명</strong></td><td><strong>&nbsp;C# 쿼리식 문법</strong></td></tr><tr><td class="has-text-align-center" data-align="center">정렬</td><td>&nbsp;OrderBy</td><td>&nbsp;오름차순으로 값을 정렬</td><td>&nbsp;orderby</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;OrderBy<br>&nbsp; &nbsp; &nbsp; &nbsp;Descending</td><td>&nbsp;내림차순으로 값을 정렬</td><td>&nbsp;orderby &#8230; descending</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ThenBy</td><td>&nbsp;오름차순으로 2차 정렬 수행</td><td>&nbsp;orderby &#8230;,&nbsp;&#8230;&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ThenBy<br>&nbsp; &nbsp; &nbsp;Descending</td><td>&nbsp;내림차순으로 2차 정렬 수행</td><td>&nbsp;orderby &#8230;,<br>&nbsp; &#8230; descending</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Reverse</td><td>&nbsp;컬렉션 요소의 순서를 거꾸로 뒤집는다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">집합</td><td>&nbsp;Distinct</td><td>&nbsp;중복 값을 제거한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Except</td><td>&nbsp;두 컬렉션 사이의 차집합을 반환한다.<br>&nbsp;임의의 한 컬렉션(a,b,c,e)에 존재하는데&nbsp;<br>다른 컬렉션(a,d,f)에는 &nbsp;존재하지 않는 요소들(b,e)을 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Intersect</td><td>&nbsp;두 컬렉션 사이의 교집합을 반환한다.<br>&nbsp;양쪽 컬렉션 양쪽에 존재하는 요소들만 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Union</td><td>&nbsp;두 컬렉션 사이의 합집합을 반환한다.<br>&nbsp;한쪽 컬렉션이&nbsp;a,b,c,d요소를 갖고 있고,&nbsp;<br>다른 컬렉션이 a,b,c,d,e &nbsp;요소를 갖고 있다면 <br>이 두 컬렉션 사이의 합집합은 a,b,c,d,e 이다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">필터링</td><td>&nbsp;OfType</td><td>&nbsp;메소드의 형식 매개 변수로 형식 변환이 가능한 값들만 추출한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Where</td><td>&nbsp;필터링할 조건을 평가하는 함수를 통과하는 값들만 추출한다.</td><td>&nbsp;where</td></tr><tr><td class="has-text-align-center" data-align="center">수량 연산</td><td>&nbsp;All</td><td>&nbsp;모든 요소가 임의의 조건을 모두 만족시키는지를 평가한다.&nbsp;<br>&nbsp;결과는 true 이거나 false 둘 중 하나이다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Any</td><td>&nbsp;모든 요소 중 단 하나의 요소라도 임의의 조건을 만족시키는지&nbsp;<br>&nbsp;평가한다. 결과는 true이거나 false 둘 중 하나이다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Contains</td><td>&nbsp;명시적 요소가 포함되어 있는지 평가한다.<br>&nbsp;결과는 true이거나 false 둘 중 하나이다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">데이터 추출</td><td>&nbsp;Select</td><td>&nbsp;값을 추출하여 시퀀스를 만든다.</td><td>&nbsp;select</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;SelectMany</td><td>&nbsp;여러 개의 데이터 원본으로부터 값을 추출하여 하나의 시퀀스를 만든다. <br>여러개의 from 절을 사용한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">데이터 분할</td><td>&nbsp;Skip</td><td>&nbsp;시퀀스에서 지정한 위치까지 요소들을 건너뛴다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;SkipWhile</td><td>&nbsp;입력된 조건 함수를 만족시키는 요소들을 건너뛴다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Take</td><td>&nbsp;시퀀스에서 지정한 요소까지 요소들을 취한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;TakeWhile</td><td>&nbsp;입력된 조건 함수를 만족시키는 요소들을 취한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">데이터 결합</td><td>&nbsp;Join</td><td>&nbsp;공통 특성을 가진 서로 다른 두 개의 데이터 소스의 객체를&nbsp;<br>연결한다. 공통 특성을 키(Key)로 삼아,&nbsp;<br>키가 일치하는 두 객체의 쌍을 추출한다.</td><td>&nbsp;Join &#8230; in &#8230; on &#8230; equals &#8230;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;GroupJoin</td><td>&nbsp;기본적으로 Join 연산자와 같은 일을 하되,&nbsp;<br>조인 결과를 그룹으로 만들어 넣는다.</td><td>&nbsp;Join &#8230; in &#8230; on &#8230; equals &#8230; into &#8230;</td></tr><tr><td class="has-text-align-center" data-align="center">데이터 그룹화</td><td>&nbsp;GroupBy</td><td>&nbsp;공통된 특성을 공유하는 요소들을 각 그룹으로 묶는다.&nbsp;<br>각 그룹은 IGrouping&lt;TKey, TElement&gt;객체로 표현된다.</td><td>&nbsp;group &#8230; by 또는 group &#8230; by &#8230; into</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ToLookup</td><td>&nbsp;키(Key) 선택 함수를 이용하여 골라낸 요소들을&nbsp;<br>Lookup&lt;TKey, TElement&gt; 형식의 객체에 삽입한다.<br>( 이 형식은 하나의 키에 여러 개의 객체를 대응시킬 때 사용하는 컬렉션이다 )</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">생성</td><td>&nbsp;DefaultIfEmpty</td><td>&nbsp;빈 컬렉션을 기본값이 할당된 싱글턴 컬렉션으로 바꾼다.&nbsp;</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Empty</td><td>&nbsp;비어 있는 컬렉션을 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Range</td><td>&nbsp;일정 범위의 숫자 시퀀스를 담고 있는 컬렉션을 생성한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Repeat</td><td>&nbsp;같은 값이 반복되는 컬렉션을 생성한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">동등 여부 평가</td><td>&nbsp;SequenceEqual</td><td>&nbsp;두 시퀀스가 서로 일치하는지를 평가한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">요소 접근</td><td>&nbsp;ElementAt</td><td>&nbsp;컬렉션으로부터 임의의 인덱스에 존재하는 요소를 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ElementAt<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OrDefault</td><td>&nbsp;컬렉션으로부터 임의의 인덱스에 존재하는 요소를 반환하되,&nbsp;<br>인덱스가 컬렉션의 범위를 벗어날 때 기본값을 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;First</td><td>&nbsp;컬렉션의 첫 번째 요소를 반환한다. 조건식이 매개 변수로&nbsp;<br>입력되는 경우 이 조건을 만족시키는 첫 번째 요소를 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;FirstOrDefault</td><td>&nbsp;First 연산자와 같은 기능을 하되, 반환할 값이 없는 경우&nbsp;<br>기본값을 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Last</td><td>&nbsp;컬렉션의 마지막 요소를 반환한다. 조건식이 매개 변수로&nbsp;<br>입력되는 경우 이 조건을 만족시키는 마지막 요소를 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;LastOrDefault</td><td>&nbsp;Last 연산자와 같은 기능을 하되, 반환할 값이 없는 경우&nbsp;<br>기본값을 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Single</td><td>&nbsp;컬렉션의 유일한 요소를 반환한다. 조건식이 매개 변수로&nbsp;<br>입력되는 경우 이&nbsp;조건을 만족시키는 유일한 요소를 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;SingleOrDefault</td><td>&nbsp;Single 연산자와 같은 기능을 하되, 반환할 값이 없거나&nbsp;<br>유일한 값이 아닌 경우 주어진 기본값을 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">형식 변환</td><td>&nbsp;AsEnumerable</td><td>&nbsp;매개 변수를 IEnumerable&lt;T&gt;로 형식 변환하여 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;AsQueryable</td><td>&nbsp;(일반화) IEnumerable 객체를&nbsp;<br>(일반화)IQueryable 형식으로 반환한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Cast</td><td>&nbsp;컬렉션의 요소들을 특정 형식으로 변환한다.</td><td>&nbsp;범위 변수를 선언할 때 명시적으로 형식을 지정하면 된다.</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;OfType</td><td>&nbsp;특정 형식으로 형식 변환할 수 있는 값만을 걸러낸다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ToArray</td><td>&nbsp;컬렉션을 배열로 변환한다. 이 메소드는 강제로 쿼리를 실행한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;TODictinoary</td><td>&nbsp;키 선택 함수에 근거해서 컬렉션의 요소를&nbsp;<br>Dictionary&lt;TKey, TValue&gt;에 삽입한다.&nbsp;<br>이 메소드는 강제로 쿼리를 실행한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ToList</td><td>&nbsp;컬렉션을 List&lt;T&gt; 형식으로 변환한다.&nbsp;<br>이 메소드는 강제로 쿼리를 실행한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;ToLookup</td><td>&nbsp;키 선택 함수에 근거해서 컬렉션의 요소를&nbsp;<br>Lookup&lt;TKey, TElement&gt;에 삽입한다.&nbsp;<br>이 메소드는 강제로 쿼리를 실행한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">연결</td><td>&nbsp;Concat</td><td>&nbsp;두 시퀀스를 하나의 시퀀스로 연결한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center">집계</td><td>&nbsp;Aggregate</td><td>&nbsp;컬렉션의 각 값에 대해 사용자가 정의한 집계 연산을 수행한다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Average</td><td>&nbsp;컬렉션의 각 값에 대한 평균을 계산한다</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Count</td><td>&nbsp;컬렉션에서 조건에 부합하는 요소의 개수를 센다</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;LongCount</td><td>&nbsp;Count와 동일한 기능을 하지만, 매우 큰 컬렉션을 대상으로 한다는 점이 다르다.</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Max</td><td>&nbsp;컬렉션에서 가장 큰 값을 반환한다</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Min</td><td>&nbsp;컬렉션에서 가장 작은 값을 반환한다</td><td>&nbsp;</td></tr><tr><td class="has-text-align-center" data-align="center"></td><td>&nbsp;Sum</td><td>&nbsp;컬렉션 내의 값의 합을 계산한다.</td><td></td></tr></tbody></table></figure>



<div style="height:98px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size"><strong>쿼리식과 메소드를 함께 사용한다면 모두 사용 가능합니다.</strong></p>



<div style="height:38px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

    }

    class MainApp
    {

        static void Main(string[] args)
        {

            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };


            //  LINQ
            double average = (from profile in arrProfiles
                              where profile.Height &lt; 180
                              select profile).Average(profile => profile.Height);

            Console.WriteLine("키 180 미만 평균 : {0}", average);
        }
    }
}</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="452" height="167" src="https://lycos7560.com/wp-content/uploads/image-635.png" alt="" class="wp-image-3294" srcset="https://lycos7560.com/wp-content/uploads/image-635.png 452w, https://lycos7560.com/wp-content/uploads/image-635-300x111.png 300w" sizes="(max-width: 452px) 100vw, 452px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using System;
using System.Linq;

namespace ConsoleApp2
{

    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

        public int Number { get; set; }

    }

    class MainApp
    {

        static void Main(string[] args)
        {

            Profile[] arrProfiles = {
                             new Profile() { Name = "정우성" , Height = 186 },
                             new Profile() { Name = "김태희" , Height = 158 },
                             new Profile() { Name = "이문세" , Height = 171 },
                             new Profile() { Name = "하동훈" , Height = 163 },
                             new Profile() { Name = "홍길동" , Height = 193 },
                             new Profile() { Name = "임꺽정" , Height = 170 }
                                    };

            //  LINQ
            var profiles = arrProfiles.Where(profile => profile.Height &lt; 175)
                                     .OrderBy(profile => profile.Height)
                                     .Select(profile => new { 
                                        Name = profile.Name,
                                        InchHeight = profile.Height * 0.393
                                     });

            foreach (var data in profiles)
            {
                Console.WriteLine("{0}  {1}",data.Name , data.InchHeight);
            }
        }
    }
}</pre>



<div style="height:44px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="507" height="217" src="https://lycos7560.com/wp-content/uploads/image-636.png" alt="" class="wp-image-3295" srcset="https://lycos7560.com/wp-content/uploads/image-636.png 507w, https://lycos7560.com/wp-content/uploads/image-636-300x128.png 300w" sizes="(max-width: 507px) 100vw, 507px" /></figure>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5698326622209671"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-5698326622209671"
     data-ad-slot="5078714126"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>
<p>The post <a href="https://lycos7560.com/c/linq-programming-c/3281/">LINQ – 이것이 C# 이다.</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/linq-programming-c/3281/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
