첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ Models/Movie.cs

using System;
using System.ComponentModel.DataAnnotations;

namespace TestProject.Models
{
    /// <summary>
    /// 영화
    /// </summary>
    public class Movie
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region ID - ID

        /// <summary>
        /// ID
        /// </summary>
        public int ID { get; set; }

        #endregion
        #region 제목 - Title

        /// <summary>
        /// 제목
        /// </summary>
        public string Title { get; set; }

        #endregion
        #region 릴리즈 일자 - ReleaseDate

        /// <summary>
        /// 릴리즈 일자
        /// </summary>
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

        #endregion
        #region 장르 - Genre

        /// <summary>
        /// 장르
        /// </summary>
        public string Genre { get; set; }

        #endregion
        #region 가격 - Price

        /// <summary>
        /// 가격
        /// </summary>
        public decimal Price { get; set; }

        #endregion
    }
}

 

728x90

 

▶ Data/DatabaseContext.cs

using Microsoft.EntityFrameworkCore;

using TestProject.Models;

namespace TestProject.Data
{
    /// <summary>
    /// 데이터베이스 컨텍스트
    /// </summary>
    public class DatabaseContext : DbContext
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 영화 - Movie

        /// <summary>
        /// 영화
        /// </summary>
        public DbSet<Movie> Movie { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - DatabaseContext(options)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="options">옵션</param>
        public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
        {
        }

        #endregion
    }
}

 

300x250

 

▶ appsettings.json

{
    "Logging" :
    {
        "LogLevel" :
        {
            "Default"                    : "Information",
            "Microsoft"                  : "Warning",
            "Microsoft.Hosting.Lifetime" : "Information"
        }
    },
    "AllowedHosts"      : "*",
    "ConnectionStrings" :
    {
        "DefaultConnection" : "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=TestDB;Integrated Security=True;"
    }
}

 

▶ Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using TestProject.Data;

namespace TestProject
{
    /// <summary>
    /// 시작
    /// </summary>
    public class Startup
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 구성 - Configuration

        /// <summary>
        /// 구성
        /// </summary>
        public IConfiguration Configuration { get; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - Startup(configuration)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="configuration">구성</param>
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 서비스 컬렉션 구성하기 - ConfigureServices(services)

        /// <summary>
        /// 서비스 컬렉션 구성하기
        /// </summary>
        /// <param name="services">서비스 컬렉션</param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<DatabaseContext>
            (
                options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
                }
            );

            services.AddRazorPages();
        }

        #endregion
        #region 구성하기 - Configure(app, environment)

        /// <summary>
        /// 구성하기
        /// </summary>
        /// <param name="app">애플리케이션 빌더</param>
        /// <param name="environment">웹 호스트 환경</param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
        {
            if(environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");

                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }

        #endregion
    }
}

 

▶ Pages/Movies/Index.cshtml

@page
@using TestProject.Models 
@model TestProject.Pages.Movies.IndexModel
@{
    ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.MovieList[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MovieList[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MovieList[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.MovieList[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach(Movie movie in Model.MovieList)
{
        <tr>
            <td>
                @Html.DisplayFor(modelItem => movie.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => movie.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => movie.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => movie.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@movie.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@movie.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@movie.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

 

▶ Pages/Movies/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;

using TestProject.Data;
using TestProject.Models;

namespace TestProject.Pages.Movies
{
    /// <summary>
    /// 인덱스 모델
    /// </summary>
    public class IndexModel : PageModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컨텍스트
        /// </summary>
        private readonly DatabaseContext context;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 영화 리스트 - MovieList

        /// <summary>
        /// 영화 리스트
        /// </summary>
        public IList<Movie> MovieList { get;set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - IndexModel(context)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="context">컨텍스트</param>
        public IndexModel(DatabaseContext context)
        {
            this.context = context;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region GET 비동기 처리하기 - OnGetAsync()

        /// <summary>
        /// GET 비동기 처리하기
        /// </summary>
        /// <returns>태스크</returns>
        public async Task OnGetAsync()
        {
            MovieList = await this.context.Movie.ToListAsync();
        }

        #endregion
    }
}

 

▶ Pages/Movies/Create.cshtml

@page
@model TestProject.Pages.Movies.CreateModel

@{
    ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>
<div>
    <a asp-page="Index">Back to List</a>
</div>
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

 

▶ Pages/Movies/Create.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Threading.Tasks;

using TestProject.Data;
using TestProject.Models;

namespace TestProject.Pages.Movies
{
    /// <summary>
    /// 생성 모델
    /// </summary>
    public class CreateModel : PageModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컨텍스트
        /// </summary>
        private readonly DatabaseContext context;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 영화 - Movie

        /// <summary>
        /// 영화
        /// </summary>
        [BindProperty]
        public Movie Movie { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - CreateModel(context)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="context">컨텍스트</param>
        public CreateModel(DatabaseContext context)
        {
            this.context = context;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region GET 처리하기 - OnGet()

        /// <summary>
        /// GET 처리하기
        /// </summary>
        /// <returns>액션 결과</returns>
        public IActionResult OnGet()
        {
            return Page();
        }

        #endregion
        #region POST 비동기 처리하기 - OnPostAsync()

        /// <summary>
        /// POST 비동기 처리하기
        /// </summary>
        /// <returns>액션 결과 태스크</returns>
        public async Task<IActionResult> OnPostAsync()
        {
            if(!ModelState.IsValid)
            {
                return Page();
            }

            this.context.Movie.Add(Movie);

            await this.context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }

        #endregion
    }
}

 

▶ Pages/Movies/Edit.cshtml

@page
@model TestProject.Pages.Movies.EditModel
@{
    ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Movie.ID" />
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>
<div>
    <a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

 

▶ Pages/Movies/Edit.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading.Tasks;

using TestProject.Data;
using TestProject.Models;

namespace TestProject.Pages.Movies
{
    /// <summary>
    /// 편집 모델
    /// </summary>
    public class EditModel : PageModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컨텍스트
        /// </summary>
        private readonly DatabaseContext context;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 영화 - Movie

        /// <summary>
        /// 영화
        /// </summary>
        [BindProperty]
        public Movie Movie { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - EditModel(context)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="context">컨텍스트</param>
        public EditModel(DatabaseContext context)
        {
            this.context = context;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region GET 비동기 처리하기 - OnGetAsync(id)

        /// <summary>
        /// GET 비동기 처리하기
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>액션 결과 태스크</returns>
        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if(id == null)
            {
                return NotFound();
            }

            Movie = await this.context.Movie.FirstOrDefaultAsync(m => m.ID == id);

            if(Movie == null)
            {
                return NotFound();
            }

            return Page();
        }

        #endregion
        #region POST 비동기 처리하기 - OnPostAsync()

        /// <summary>
        /// POST 비동기 처리하기
        /// </summary>
        /// <returns>액션 결과 태스크</returns>
        public async Task<IActionResult> OnPostAsync()
        {
            if(!ModelState.IsValid)
            {
                return Page();
            }

            this.context.Attach(Movie).State = EntityState.Modified;

            try
            {
                await this.context.SaveChangesAsync();
            }
            catch(DbUpdateConcurrencyException)
            {
                if(!MovieExists(Movie.ID))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return RedirectToPage("./Index");
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 영화 존재 여부 구하기 - MovieExists(id)

        /// <summary>
        /// 영화 존재 여부 구하기
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>영화 존재 여부</returns>
        private bool MovieExists(int id)
        {
            return this.context.Movie.Any(e => e.ID == id);
        }

        #endregion
    }
}

 

▶ Pages/Movies/Delete.cshtml

@page
@model TestProject.Pages.Movies.DeleteModel
@{
    ViewData["Title"] = "Delete";
}
<h1>Delete</h1>
<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.ReleaseDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.ReleaseDate)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.Genre)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.Genre)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.Price)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.Price)
        </dd>
    </dl>
    <form method="post">
        <input type="hidden" asp-for="Movie.ID" />
        <input type="submit" value="Delete" class="btn btn-danger" /> |
        <a asp-page="./Index">Back to List</a>
    </form>
</div>

 

▶ Pages/Movies/Delete.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;

using TestProject.Data;
using TestProject.Models;

namespace TestProject.Pages.Movies
{
    /// <summary>
    /// 삭제 모델
    /// </summary>
    public class DeleteModel : PageModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컨텍스트
        /// </summary>
        private readonly DatabaseContext context;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 영화 - Movie

        /// <summary>
        /// 영화
        /// </summary>
        [BindProperty]
        public Movie Movie { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - DeleteModel(context)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="context">컨텍스트</param>
        public DeleteModel(DatabaseContext context)
        {
            this.context = context;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region GET 비동기 처리하기 - OnGetAsync(id)

        /// <summary>
        /// GET 비동기 처리하기
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>액션 결과 태스크</returns>
        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if(id == null)
            {
                return NotFound();
            }

            Movie = await this.context.Movie.FirstOrDefaultAsync(m => m.ID == id);

            if(Movie == null)
            {
                return NotFound();
            }

            return Page();
        }

        #endregion
        #region POST 비동기 처리하기 - OnPostAsync(id)

        /// <summary>
        /// POST 비동기 처리하기
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>액션 결과 태스크</returns>
        public async Task<IActionResult> OnPostAsync(int? id)
        {
            if(id == null)
            {
                return NotFound();
            }

            Movie = await this.context.Movie.FindAsync(id);

            if(Movie != null)
            {
                this.context.Movie.Remove(Movie);

                await this.context.SaveChangesAsync();
            }

            return RedirectToPage("./Index");
        }

        #endregion
    }
}

 

▶ Pages/Movies/Details.cshtml

@page
@model TestProject.Pages.Movies.DetailsModel
@{
    ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.ReleaseDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.ReleaseDate)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.Genre)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.Genre)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Movie.Price)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Movie.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-page="./Edit" asp-route-id="@Model.Movie.ID">Edit</a> |
    <a asp-page="./Index">Back to List</a>
</div>

 

▶ Pages/Movies/Details.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;

using System.Threading.Tasks;

using TestProject.Data;
using TestProject.Models;

namespace TestProject.Pages.Movies
{
    /// <summary>
    /// 상세 모델
    /// </summary>
    public class DetailsModel : PageModel
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컨텍스트
        /// </summary>
        private readonly DatabaseContext context;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 영화 - Movie

        /// <summary>
        /// 영화
        /// </summary>
        [BindProperty]
        public Movie Movie { get; set; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - DetailsModel(context)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="context">컨텍스트</param>
        public DetailsModel(DatabaseContext context)
        {
            this.context = context;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region GET 비동기 처리하기 - OnGetAsync(id)

        /// <summary>
        /// GET 비동기 처리하기
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns>액션 결과 태스크</returns>
        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if(id == null)
            {
                return NotFound();
            }

            Movie = await context.Movie.FirstOrDefaultAsync(m => m.ID == id);

            if(Movie == null)
            {
                return NotFound();
            }

            return Page();
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요