Friday 22 May 2020

CRUD operations using CORE(3.1) MVC,AutoMapper,Repository, Dependency Injection, EF core code first approach & implementing store procedure in EF core.


Dot net core :

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace USINGSP.Models
{
    public class TEST
    {
        [Key]
        public int EID { get; set; }
        [MaxLength(50)]
        public string NAME { get; set; }
        public string ADDRESS { get; set; }
        [MaxLength(50)]
        public string GENDER { get; set; }

    }
}
--
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace USINGSP.Models
{
    public class AppDbContext:DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
        {

        }
        public DbSet<TEST> Tests { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;database=SankarDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
        }
    }
}
--
Add a migration using below command.
 Add-Migration  3rd
 Write ur store procedure in the 3rd.cs file. The file looks like.

using Microsoft.EntityFrameworkCore.Migrations;

namespace USINGSP.Migrations
{
    public partial class _3rd : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            var sp = @"CREATE procedure dbo.SP_DML1
                        (
                        @TID int=null,
                        @NAME nvarchar(50)=null,
                        @ADDRESS nvarchar(max)=null,
                        @GENDER nvarchar(50)=null,
                        @MARK int
                        )
                        as
                        begin
                        begin Try
                        if @MARK=1
                        begin
                        insert into Tests(NAME,ADDRESS,GENDER) values(@NAME,@ADDRESS,@GENDER)
                        end
                        else if @MARK=2
                        begin
                        update Tests set NAME=@NAME,ADDRESS=@ADDRESS,GENDER=@GENDER where EID=@TID
                        end
                        else if @MARK=3
                        begin
                        delete from  Tests  where EID=@TID
                        end
                        end Try
                        begin catch
                        SELECT  
                                    ERROR_NUMBER() AS ErrorNumber  
                                    ,ERROR_SEVERITY() AS ErrorSeverity  
                                    ,ERROR_STATE() AS ErrorState  
                                    ,ERROR_PROCEDURE() AS ErrorProcedure  
                                    ,ERROR_LINE() AS ErrorLine  
                                    ,ERROR_MESSAGE() AS ErrorMessage;  
                        end catch
                            end";
            migrationBuilder.Sql(sp);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {

        }
    }
}
after that you must use below command.
update-database
---
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;

namespace USINGSP.Models
{
    public class TESTVM
    {
        public TESTVM()
        {
            LTEST = new List<TEST>();
        }
        public int EID { get; set; }
        [Required(ErrorMessage ="Name should not be blank.")]
        public string NAME { get; set; }
        [Required(ErrorMessage = "Address should not be blank.")]
        [DataType(DataType.MultilineText)]
        public string ADDRESS { get; set; }
        [Required(ErrorMessage = "Gender should not be blank.")]
        public string GENDER { get; set; }
        public string MESSAGE { get; set; }
        public List<TEST> LTEST { get; set; }
    }
}

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

namespace USINGSP.Models
{
 public interface IRepository
    {
        Task<IEnumerable<TEST>> Gets();
        Task<TEST> Get(int EID);
        Task<TEST> Save(TEST test);
        Task<TEST> Update(TEST test);
        Task<TEST> Delete(int EID);

    }
}
--
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace USINGSP.Models
{
    public class Repository : IRepository
    {
        #region
        private readonly AppDbContext context;
        #endregion
        public Repository(AppDbContext context)
        {
            this.context = context;
        }
        public async Task<TEST> Delete(int EID)
        {
            await context.Database.ExecuteSqlRawAsync($"EXEC dbo.SP_DML1 @TID={EID},@MARK={3}");
            return await context.Tests.FirstOrDefaultAsync();
        }

        public async Task<TEST> Get(int EID)
        {
            return await context.Tests.FromSqlRaw($"select * from Tests where EID={EID}").FirstAsync();
        }

        public async Task<IEnumerable<TEST>> Gets()
        {
            return await context.Tests.FromSqlRaw("select * from Tests").ToListAsync();
        }

        public async Task<TEST> Save(TEST test)
        {

           await context.Database.ExecuteSqlRawAsync($"EXEC dbo.SP_DML1 @NAME={test.NAME},@ADDRESS={test.ADDRESS},@GENDER={test.GENDER},@MARK={1}");
            return await context.Tests.FirstOrDefaultAsync();

        }

        public async Task<TEST> Update(TEST test)
        {
            await context.Database.ExecuteSqlRawAsync($"exec dbo.SP_DML1  @TID={test.EID},@NAME={test.NAME},@ADDRESS={test.ADDRESS},@GENDER={test.GENDER},@MARK={2}");
            return await context.Tests.FirstOrDefaultAsync();
        }
    }
}
--
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace USINGSP.Models
{
    public class MappingProfile:Profile
    {
        public MappingProfile()
        {
            CreateMap<TEST, TESTVM>();
            CreateMap<TESTVM, TEST>();
        }
    }
}
--
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using USINGSP.Models;

namespace USINGSP
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddDbContext<AppDbContext>();
            services.AddScoped<IRepository, Repository>();
            services.AddAutoMapper(typeof(MappingProfile));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
--
Controller :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using USINGSP.Models;

namespace USINGSP.Controllers
{
    public class EmpController : Controller
    {
        #region
        private readonly IRepository repository;
        private readonly IMapper mapper;
        private static string message;
        #endregion
        public EmpController(IRepository repository, IMapper mapper)
        {
            this.repository = repository;
            this.mapper = mapper;
        }
        [HttpGet]
        public async Task<IActionResult> Index(int? id)
        {
            TESTVM tESTVM = new TESTVM();
            tESTVM.LTEST = (List<TEST>)await repository.Gets();
            if (id > 0)
            {
                TEST test = await repository.Get(id.Value);
                mapper.Map(test, tESTVM);
            }
            if (!string.IsNullOrEmpty(message))
            {
                tESTVM.MESSAGE = message;
                message = "";
            }
            else
                tESTVM.MESSAGE = "";

            return View(tESTVM);
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Index(TESTVM tESTVM)
        {
            try
            {
                TEST test = new TEST();
                if (ModelState.IsValid)
                {
                    mapper.Map(tESTVM, test);
                    if (tESTVM.EID > 0)
                    {
                        await repository.Update(test);
                        message = "Data Updated Successfully.";
                    }
                    else
                    {

                        await repository.Save(test);
                        message = "Data Saved Successfully.";
                    }
                    return RedirectToAction("Index", new { id = 0 });
                }
                else
                    return View(tESTVM);
            }
            catch (Exception ex)
            {
                message = ex.Message;
                throw;
            }
        }
        [HttpGet]
        public async Task<IActionResult> Delete(int id)
        {
            try
            {
                await repository.Delete(id);
                message = "Data Deleted Successfully.";
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                message = ex.Message;
                throw;
            }
        }
    }
}

Index View :
@model USINGSP.Models.TESTVM

@{
    ViewData["Title"] = "Index";
}

    <style type="text/css">
        .xxx {
            background-color: #0069d9;
            border-color: #0062cc;
            color: white
        }

        .modal-header {
            display: block !important;
        }

        .modal-title {
            float: left;
        }

        .modal-header .close {
            float: right;
        }
    </style>
<div class="row">
    <div class="col-md-4">
        <form asp-action="Index" asp-antiforgery="true">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">
                <label asp-for="NAME" class="control-label"></label>
                <input asp-for="NAME" class="form-control" />
                <input asp-for="EID" type="hidden" />
                <span asp-validation-for="NAME" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ADDRESS" class="control-label"></label>
                <input asp-for="ADDRESS" class="form-control" />
                <span asp-validation-for="ADDRESS" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="GENDER" class="control-label"></label>
                <input asp-for="GENDER" type="radio" value="Male" />Male
                <input asp-for="GENDER" type="radio" value="Female" />Female
                <span asp-validation-for="GENDER" class="text-danger"></span>
            </div>

            <div class="form-group">
                <input type="submit" value="Create" style="width:80px" class="btn btn-primary" />
                <input type="reset" value="Reset" style="width:80px" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>
<div class="row">
    <partial name="ListPV" model="Model.LTEST" />
</div>
<partial name="ConfirmPV" />
@{ if (Model.MESSAGE != "")
    {
        <partial name="AlertPV" model="new Alert() { Message=Model.MESSAGE }" />
    }
}
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

ListPV Partilaview :

@model IEnumerable<TEST>


<table class="table table-bordered table-hover">
    <thead class="xxx">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.EID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.NAME)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ADDRESS)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.GENDER)
            </th>
            <th>ACTION</th>
        </tr>
    </thead>
    <tbody>
        @{
            if (Model.Count() > 0)
            {
                @foreach (var item in Model)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.EID)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.NAME)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.ADDRESS)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.GENDER)
                        </td>
                        <td>
                            @Html.ActionLink("Edit", "Index", new { id = item.EID }) |
                            <a href="#" onclick="confirmDelete('@Url.Content("~/Emp/Delete/" + item.EID)')">Delete</a>
                        </td>
                    </tr>
                }
            }
            else
            {
                <tr><td colspan="5" class="text-danger text-center">No Records Found.</td></tr>
            }
        }


    </tbody>
</table>





Wednesday 20 May 2020

CRUD operations using CORE(3.1) MVC,AutoMapper,Generic Repository & Dependency Injection, core EF code first approach ,Bootstrap modal popup,datepicker & multiselect drop down.




Dot net core code :

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel;

namespace Bootstrapdatepicker.Models
{
    public class EMP
    {
        [Key]
        public int EID { get; set; }
        [MaxLength(50)]
        public string NAME { get; set; }
        public string ADDRESS { get; set; }
        [MaxLength(50)]
        public string PASSWORD { get; set; }
        [MaxLength(50)]
        public string EMAIL { get; set; }
        [DefaultValue("getutcdate()")]
        public DateTime DOJ { get; set; }
        [MaxLength(50)]
        public string GENDER { get; set; }
        public int CID { get; set; }
        public int SID { get; set; }
    }
}
--
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Bootstrapdatepicker.Models
{
    public class EMPVM
    {
        public EMPVM()
        {
            HOBBY = new List<string>();
            LHOBBY = new List<SelectListItem>();
            LCOUNTRY = new List<SelectListItem>();
            LSTATE = new List<SelectListItem>();
        }

        public int EID { get; set; }
        [Required(ErrorMessage ="Name should not be blank.")]
        public string NAME { get; set; }
        [Required(ErrorMessage = "Addrerss should not be blank.")]
        [DataType(DataType.MultilineText)]
        public string ADDRESS { get; set; }
        [Required(ErrorMessage = "Password should not be blank.")]
        [StringLength(8, MinimumLength = 6, ErrorMessage = "Password length between 6 to 8 charecters long.")]
        [DataType(DataType.Password)]
        public string PASSWORD { get; set; }
        [Required(ErrorMessage = "Confirm password should not be blank.")]
        [Compare("PASSWORD",ErrorMessage ="Password and confirm password must be same.")]
        [DataType(DataType.Password)]
        [Display(Name ="CONFIRM PASSWORD")]
        public string CPASSWORD { get; set; }
        [Required(ErrorMessage = "Email should not be blank.")]
        [EmailAddress(ErrorMessage ="Invalid Email id.")]
        public string EMAIL { get; set; }
        [Required(ErrorMessage = "Please select a date.")]
        public DateTime DOJ { get; set; }
        [Required(ErrorMessage = "Please select a gender.")]
        public string GENDER { get; set; }
        [Required(ErrorMessage = "Please select a hobby.")]
        public List<string> HOBBY { get; set; }
        public List<SelectListItem> LHOBBY { get; set; }
        [Required(ErrorMessage = "Please select a country.")]
        public int COUNTRY { get; set; }
        public List<SelectListItem> LCOUNTRY { get; set; }
        [Required(ErrorMessage = "Please select a state.")]
        public int STATE { get; set; }
        public List<SelectListItem> LSTATE { get; set; }
        public string Message { get; set; }
        public void fillddl(List<SelectListItem> lh,List<SelectListItem> lc, List<SelectListItem> ls=null)
        {
            LHOBBY = lh;
            LCOUNTRY = lc;
            LSTATE = ls;
        }

    }
}
--
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace Bootstrapdatepicker.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
        {
                
        }
        public DbSet<COUNTRY> Countries { get; set; }
        public DbSet<STATE> States { get; set; }
        public DbSet<HOBBY> Hobbies { get; set; }
        public DbSet<EMP> Emps { get; set; }
        public DbSet<HMAP> Hmaps { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<COUNTRY>().HasData(new COUNTRY { CID = 1, CNAME = "X" }, new COUNTRY { CID = 2, CNAME = "Y" }, new COUNTRY { CID = 3, CNAME = "Z" });
            modelBuilder.Entity<HOBBY>().HasData(new HOBBY { HID = 1, HNAME = "Cricket" }, new HOBBY { HID = 2, HNAME = "Football" }, new HOBBY { HID = 3, HNAME = "Baseball" }, new HOBBY { HID = 4, HNAME = "Hockey" });
            modelBuilder.Entity<STATE>().HasData(new STATE { SID = 1, SNAME = "A",CID=1 }, new STATE { SID = 2, SNAME = "B", CID = 1 }, new STATE { SID = 3, SNAME = "C", CID = 2 }, new STATE { SID = 4, SNAME = "D", CID = 2 }, new STATE { SID = 5, SNAME = "E", CID = 3 }, new STATE { SID = 6, SNAME = "F", CID = 3 });
        }
    }
}
--
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Bootstrapdatepicker.Models
{
    public interface IRepository<T> where T:class
    {
        Task<IEnumerable<T>> Gets();
        Task<T> Get(int ID);
        Task<T> Save(T t);
        Task<T> Update(T t);
        Task<T> Delete(int ID);
        Task<T> SaveAll(List<T> lst);
        Task<T> DeleteAll(List<T> lst);

    }
}
--
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace Bootstrapdatepicker.Models
{
    public class Repository<T> : IRepository<T> where T : class
    {
        #region
        private readonly AppDbContext Context;
        #endregion
        public Repository(AppDbContext Context)
        {
            this.Context = Context;
        }
        public async Task<IEnumerable<T>> Gets()
        {
            return await Context.Set<T>().ToListAsync();
        }
        public async Task<T> Get(int ID)
        {
            return await Context.Set<T>().FindAsync(ID);
        }

        public async Task<T> Save(T t)
        {
            await Context.Set<T>().AddAsync(t);
            await Context.SaveChangesAsync();
            return t;
        }

        public async Task<T> SaveAll(List<T> lst)
        {
            await Context.Set<T>().AddRangeAsync(lst);
            await Context.SaveChangesAsync();
            return lst.First();
        }

        public async Task<T> Update(T t)
        {
            Context.Set<T>().Update(t);
            await Context.SaveChangesAsync();
            return t;
        }
        public async Task<T> Delete(int ID)
        {
            T t = await Context.Set<T>().FindAsync(ID);
            Context.Set<T>().Remove(t);
            await Context.SaveChangesAsync();
            return t;
        }

        public async Task<T> DeleteAll(List<T> lst)
        {
            Context.Set<T>().RemoveRange(lst);
            await Context.SaveChangesAsync();
            return lst.First();
        }
    }
}
--
Using AutoMapper in ASP.NET Core
To use AutoMapper in an ASP.NET Core project, install AutoMapper.Extensions.Microsoft.DependencyInjection nuget package. This package has a dependency on AutoMapper, so it will also be installed.
--
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Bootstrapdatepicker.Models
{
    public class MappingProfile:Profile
    {
        public MappingProfile()
        {
            CreateMap<EMP,EMPVM>()
           .ForMember(dest => dest.CPASSWORD,
                           opt => opt.MapFrom(src => src.PASSWORD))
            .ForMember(dest => dest.COUNTRY,
                           opt => opt.MapFrom(src => src.CID))
              .ForMember(dest => dest.STATE,
                           opt => opt.MapFrom(src => src.SID));
            CreateMap<EMPVM,EMP>()
                .ForMember(dest => dest.PASSWORD,
                           opt => opt.MapFrom(src => src.CPASSWORD))
            .ForMember(dest => dest.CID,
                           opt => opt.MapFrom(src => src.COUNTRY))
              .ForMember(dest => dest.SID,
                           opt => opt.MapFrom(src => src.STATE));
        }
    }
}
--
Add AutoMapper Services
In ConfigureServices method of the Startup class, add AutoMapper services. 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Bootstrapdatepicker.Models;
using Microsoft.EntityFrameworkCore;

namespace Bootstrapdatepicker
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddAutoMapper(typeof(MappingProfile));
            services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;DataBase=TestApi;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"));
            services.AddScoped<IRepository<EMP>, Repository<EMP>>();
            services.AddScoped<IRepository<COUNTRY>, Repository<COUNTRY>>();
            services.AddScoped<IRepository<STATE>, Repository<STATE>>();
            services.AddScoped<IRepository<HOBBY>, Repository<HOBBY>>();
            services.AddScoped<IRepository<HMAP>, Repository<HMAP>>();
          
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

--
Controller :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Bootstrapdatepicker.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
using AutoMapper;

namespace Bootstrapdatepicker.Controllers
{
    public class EmpController : Controller
    {
        #region
        private readonly IRepository<EMP> eRepository;
        private readonly IRepository<COUNTRY> cRepository;
        private readonly IRepository<STATE> sRepository;
        private readonly IRepository<HOBBY> hRepository;
        private readonly IRepository<HMAP> mRepositor;
        private static string message;
        private readonly IMapper mapper;
        #endregion
        public EmpController(IRepository<EMP> eRepository,
            IRepository<COUNTRY> cRepository,
            IRepository<STATE> sRepository,
            IRepository<HOBBY> hRepository,
            IRepository<HMAP> mRepository,
            IMapper mapper
            )
        {
            this.eRepository = eRepository;
            this.cRepository = cRepository;
            this.sRepository = sRepository;
            this.hRepository = hRepository;
            this.mRepositor = mRepository;
            this.mapper = mapper;
        }
        [HttpGet]
        public async Task<IActionResult> Index()
        {
            IndexVM vm = new IndexVM();
            if (!string.IsNullOrEmpty(message))
            {
                vm.Message = message;
                message = null;
            }
            else
                vm.Message = "";
            var data = await eRepository.Gets();
            vm.lst = data.ToList();
            return View(vm);
        }
        [HttpGet]
        public async Task<IActionResult> Fill(int CID)
        {
            var data = await sRepository.Gets();
            return Json(data.Where(m => m.CID == CID).ToList());
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> AddorEdit(EMPVM eMPVM)
        {
            EMP emp = new EMP();
            HMAP hm;
            mapper.Map(eMPVM, emp);
            if (eMPVM.EID == 0)
            {
                emp = await eRepository.Save(emp);
                hm = await mRepositor.SaveAll(eMPVM.HOBBY.Select(m => new HMAP { EID = emp.EID, HID = Convert.ToInt32(m) }).ToList());
                message = "Data Saved Successfully.";
            }
            else
            {
                emp = await eRepository.Update(emp);
                hm = await mRepositor.DeleteAll(mRepositor.Gets().Result.Where(m => m.EID == emp.EID).ToList());
                hm = await mRepositor.SaveAll(eMPVM.HOBBY.Select(m => new HMAP { EID = emp.EID, HID = Convert.ToInt32(m) }).ToList());
                message = "Data Updated Successfully.";
            }

            return RedirectToAction("Index");
        }
        [HttpGet]
        public async Task<IActionResult> OpenPopup(int id)
        {
            EMPVM eMPVM = new EMPVM();
            EMP emp = new EMP();
            var datac = await cRepository.Gets();
            var datah = await hRepository.Gets();
            if (id == 0)
            {
                eMPVM.fillddl(datah.Select(m => new SelectListItem { Value = m.HID.ToString(), Text = m.HNAME }).ToList(), datac.Select(m => new SelectListItem { Value = m.CID.ToString(), Text = m.CNAME }).ToList());
                return PartialView("AddOrEdit", eMPVM);
            }
            else
            {
                emp = await eRepository.Get(id);
                mapper.Map(emp, eMPVM);
                eMPVM.fillddl(datah.Select(m => new SelectListItem { Value = m.HID.ToString(), Text = m.HNAME }).ToList(), datac.Select(m => new SelectListItem { Value = m.CID.ToString(), Text = m.CNAME }).ToList(), sRepository.Gets().Result.Where(m => m.CID == eMPVM.COUNTRY).Select(m => new SelectListItem { Value = m.SID.ToString(), Text = m.SNAME }).ToList());
                var datam = await mRepositor.Gets();
                eMPVM.HOBBY = datam.Where(m => m.EID == eMPVM.EID).Select(m => m.HID.ToString()).ToList();
                return PartialView("Edit", eMPVM);
            }
        }
        [HttpGet]
        public async Task<IActionResult> Delete(int id)
        {
            EMP emp = await eRepository.Delete(id);
            HMAP hm = await mRepositor.DeleteAll(mRepositor.Gets().Result.Where(m => m.EID == id).ToList());
            message = "Data Deleted Successfully.";
            return RedirectToAction("Index");
        }

    }
}
--
Index View :

@model IndexVM

@{
    ViewData["Title"] = "Index";
}

<style type="text/css">
    .xxx {
        background-color: #0069d9;
        border-color: #0062cc;
        color: white
    }

    .modal-header {
        display: block !important;
    }

    .modal-title {
        float: left;
    }

    .modal-header .close {
        float: right;
    }

    .multiselect {
        width: 300px;
    }

    .multiselect-container {
        width: 300px;
    }
</style>
<p>
    <a class="btn btn-primary xxx" id="btnAdd" href="#">Add New</a>
</p>
<div style="border:1px solid #000000">
    <table class="table table-bordered table-hover" id="tb">
        <thead class="xxx">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.lst[0].EID)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.lst[0].NAME)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.lst[0].ADDRESS)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.lst[0].EMAIL)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.lst[0].DOJ)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.lst[0].GENDER)
                </th>

                <th>ACTION</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.lst)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.EID)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.NAME)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ADDRESS)
                    </td>

                    <td>
                        @Html.DisplayFor(modelItem => item.EMAIL)
                    </td>
                    <td>
                        @{
                            string s = string.Format("{0:dd-MMM-yy}", item.DOJ);
                        }
                        @s
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.GENDER)
                    </td>
                    <td>
                        <a href="#" class="edit">Edit</a> |
                        <a href="#" onclick="confirmDelete('@Url.Content("~/Emp/Delete/" + item.EID)')">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>

<div id="dv"></div>
<partial name="ConfirmPV" />
@{
    if (@Model.Message != "")
    {
        <partial name="AlertPV" model='new Alert() { AlertMessage=Model.Message }' />
    }
}
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script type="text/javascript">
       
        $(function () {
           
       
             var table = $("#tb").DataTable({
                "order": [[0, "asc"]],
                "lengthMenu": [[2, 10, 25, 50, -1], [2, 10, 25, 50, "All"]],
                "scroller": true,
                "orderClasses": false,
            });
            var modalContainer = $('#dv');
             modalContainer.find("[id='deleteModal1']").on('click', '[data-toggle=dropdown]', function () {
                var opened = $(this).parent().hasClass("open");
                if (!opened) {
                    $('.btn-group').addClass('open');
                    $("button.multiselect").attr('aria-expanded', 'true');
                } else {
                    $('.btn-group').removeClass('open');
                    $("button.multiselect").attr('aria-expanded', 'false');
                }
            });
            $('#btnAdd').click(function () {
                fx(0);
            });
            $('.table').on("click",".edit", function (e) {
                var id = $(this).closest("tr").find("td:first").text();
                e.stopPropagation();
                fx(id);
            });
            function fx(Id) {
             $.ajax({
                    "url":  '@Url.Action("OpenPopup", "Emp")',
                    type: 'Get',
                    datatype: 'json',
                    cache: false,
                    async: true,
                    data: {id:Id},
                    success: function (data) {
                       modalContainer.empty().append(data);
                        modalContainer.find("[id='deleteModal1']").modal('show');
                        //modalContainer.find("[id='deleteModal1']").find("[id='HOBBY']").multiselect();
                    },
                    error: function (t) {
                        alert(t.responseText);
                    }
                });
            }
        });
            
    </script>
}
--
AddOrEdit Partilaview :

@model EMPVM



<link href="~/Bootstrapdatepicer/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/Bootstrapdatepicer/js/moment.min.js"></script>
<script src="~/dist/js/bootstrap-multiselect.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Bootstrapdatepicer/js/bootstrap-datetimepicker.min.js"></script>

<form asp-action="AddorEdit" asp-antiforgery="true">
    <div class="modal fade" id="deleteModal1" data-keyboard="false" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                    <h4 class="modal-title" id="myModalLabel">Add Or Edit</h4>
                </div>
                <div class="modal-body">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

                    <div class="form-group">
                        <label asp-for="NAME" class="control-label"></label>
                        <input asp-for="NAME" class="form-control" />
                        <input asp-for="EID" type="hidden" />
                        <span asp-validation-for="NAME" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="ADDRESS" class="control-label"></label>
                        <textarea asp-for="ADDRESS" class="form-control"></textarea>
                        <span asp-validation-for="ADDRESS" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="PASSWORD" class="control-label"></label>
                        <input asp-for="PASSWORD" class="form-control" />
                        <span asp-validation-for="PASSWORD" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="CPASSWORD" class="control-label"></label>
                        <input asp-for="CPASSWORD" class="form-control" />
                        <span asp-validation-for="CPASSWORD" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="EMAIL" class="control-label"></label>
                        <input asp-for="EMAIL" class="form-control" />
                        <span asp-validation-for="EMAIL" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="DOJ" class="control-label"></label>
                       
                            <input asp-for="DOJ" class="form-control" />
            
                        <span asp-validation-for="DOJ" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="GENDER" class="control-label"></label>
                        <input type="radio" asp-for="GENDER" value="Male" />Male
                        <input type="radio" asp-for="GENDER" value="Female" />Female
                        <span asp-validation-for="GENDER" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="HOBBY" class="control-label"></label>
                        <select asp-for="HOBBY" multiple class="form-control" asp-items="Model.LHOBBY">
                        </select>
                        <span asp-validation-for="COUNTRY" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="COUNTRY" class="control-label"></label>
                        <select asp-for="COUNTRY" class="form-control" asp-items="Model.LCOUNTRY">
                            <option value="">Select</option>
                        </select>
                        <span asp-validation-for="COUNTRY" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="STATE" class="control-label"></label>
                        <select asp-for="STATE" class="form-control" asp-items="Model.LSTATE">
                            <option value="">Select</option>
                        </select>
                        <span asp-validation-for="STATE" class="text-danger"></span>
                    </div>
                </div>
                <div class="modal-footer">
                    <input type="submit" id="deleteConfirm" value="Create" class="btn btn-primary" style="width:80px" />
                    <input type="button" value="Cancel" class="btn btn-primary focusedButton" data-dismiss="modal" style="width:80px" />
                </div>
            </div>
        </div>
    </div>
</form>


<script type="text/javascript">
    $(function () {


        $('#HOBBY').multiselect();
       
        $('#DOJ').datetimepicker({
            format:'DD-MM-YYYY'
        }); 
        // $("button.multiselect").on("click", function () {
        //    $(this).parent().addClass("open");
        //});
        $('#COUNTRY').change(function () {
                $('#STATE').empty();
                $('#STATE').append("<option>Select</option>");
                $.ajax({
                    url: '@Url.Action("Fill","Emp")',
                    type: 'Get',
                    dataType: 'Json',
                    contentType: 'application/json; charset=utf-8',
                    data: { CID: $(this).val() },
                    success: function (data) {
                        $.each(data, function (i, v) {
                            $('#STATE').append("<option value='" + v.SID + "'>" + v.SNAME + "</option>");
                        })
                    }
                });
            });
    });
</script>
Edit Partialview :

@model EMPVM



<link href="~/Bootstrapdatepicer/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/Bootstrapdatepicer/js/moment.min.js"></script>
<script src="~/dist/js/bootstrap-multiselect.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Bootstrapdatepicer/js/bootstrap-datetimepicker.min.js"></script>


<form asp-action="AddorEdit" asp-antiforgery="true">
    <div class="modal fade" id="deleteModal1" data-keyboard="false" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                    <h4 class="modal-title" id="myModalLabel">Add Or Edit</h4>
                </div>
                <div class="modal-body">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

                    <div class="form-group">
                        <label asp-for="NAME" class="control-label"></label>
                        <input asp-for="NAME" class="form-control" />
                        <input asp-for="EID" type="hidden" />
                        <input asp-for="PASSWORD" type="hidden" />
                        <input asp-for="CPASSWORD" type="hidden" />
                        <span asp-validation-for="NAME" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="ADDRESS" class="control-label"></label>
                        <textarea asp-for="ADDRESS" class="form-control"></textarea>
                        <span asp-validation-for="ADDRESS" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="EMAIL" class="control-label"></label>
                        <input asp-for="EMAIL" class="form-control" />
                        <span asp-validation-for="EMAIL" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="DOJ" class="control-label"></label>
                        <input asp-for="DOJ" class="form-control" />
                        <span asp-validation-for="DOJ" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="GENDER" class="control-label"></label>
                        <input type="radio" asp-for="GENDER" value="Male" />Male
                        <input type="radio" asp-for="GENDER" value="Female" />Female
                        <span asp-validation-for="GENDER" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="HOBBY" class="control-label"></label>
                        <select asp-for="HOBBY" multiple class="form-control" asp-items="Model.LHOBBY">
                        </select>
                        <span asp-validation-for="COUNTRY" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="COUNTRY" class="control-label"></label>
                        <select asp-for="COUNTRY" class="form-control" asp-items="Model.LCOUNTRY">
                            <option value="">Select</option>
                        </select>
                        <span asp-validation-for="COUNTRY" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="STATE" class="control-label"></label>
                        <select asp-for="STATE" class="form-control" asp-items="Model.LSTATE">
                            <option value="">Select</option>
                        </select>
                        <span asp-validation-for="STATE" class="text-danger"></span>
                    </div>
                </div>
                <div class="modal-footer">
                    <input type="submit" id="deleteConfirm" value="Create" class="btn btn-primary" style="width:80px" />
                    <input type="button" value="Cancel" class="btn btn-primary focusedButton" data-dismiss="modal" style="width:80px" />
                </div>
            </div>
        </div>
    </div>
</form>


<script type="text/javascript">
    $(function () {
          $('#DOJ').datetimepicker({
            format:'DD-MM-YYYY'
        });
        $('#HOBBY').multiselect();
        //$("button.multiselect").on("click", function () {
        //    $(this).parent().addClass("open");
        //});
        $('#COUNTRY').change(function () {
                $('#STATE').empty();
                $('#STATE').append("<option>Select</option>");
                $.ajax({
                    url: '@Url.Action("Fill","Emp")',
                    type: 'Get',
                    dataType: 'Json',
                    contentType: 'application/json; charset=utf-8',
                    data: { CID: $(this).val() },
                    success: function (data) {
                        $.each(data, function (i, v) {
                            $('#STATE').append("<option value='" + v.SID + "'>" + v.SNAME + "</option>");
                        })
                    }
                });
            });
    });
</script>