使用实体框架核心和ViewModel进行代码优先

时间:2020-01-12 12:52:43

标签: asp.net-mvc entity-framework-core ef-code-first

我是MVC和Entity Framework的新手,已经决定使用ViewModels使用Code First方法。

我尝试了许多不同的教程,但是我没有尝试过使用EF Core中的Code First和ViewModels。

我的模型

public class Intermediary
{
    public int IntermediaryID { get; set; }
    public string RegisteredName { get; set; }
    public string TradingName { get; set; }
    public int Registration { get; set; }
    public int VATNumber { get; set; }
    public int FSPNumber { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }

    public ICollection<Branch> Branches { get; set; }
}

public class Branch
{
    public int BranchID { get; set; }
    public string Name { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public Intermediary Intermediary { get; set; }
}

我的ViewModel

public class IntermediariesViewModel
{
    public int ID { get; set; }
    public Intermediary Intermediary { get; set; }
    public virtual ICollection<Branch> Branches { get; set; }
}

我的数据上下文类

public class BizDevHubContext : DbContext
{
    public BizDevHubContext(DbContextOptions<BizDevHubContext> options) : base(options)
    {
    }

    public DbSet<Intermediary> Intermediaries { get; set; }
    public DbSet<Branch> Branches { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Intermediary>().ToTable("Intermediary");
        modelBuilder.Entity<Branch>().ToTable("Branch");
    }
}

我的初始化器类

public static class DbInitializer
{
    public static void Initialize(BizDevHubContext context)
    {
        context.Database.EnsureCreated();

        if (context.Intermediaries.Any())
        {
            return;   // DB has been seeded
        }

        var intermediaries = new Intermediary[]
        {
        new Intermediary{RegisteredName="Carson",TradingName="Alexander",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Meredith",TradingName="Alonso",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Arturo",TradingName="Anand",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Gytis",TradingName="Barzdukas",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Yan",TradingName="Li",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Peggy",TradingName="Justice",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Laura",TradingName="Norman",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Intermediary{RegisteredName="Nino",TradingName="Olivetto",CreatedDate=DateTime.Now}
        };
        foreach (Intermediary i in intermediaries)
        {
            context.Intermediaries.Add(i);
        }
        context.SaveChanges();

        var branches = new Branch[]
        {
        new Branch{Name="Bloemfontein",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Branch{Name="Cape Town",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Branch{Name="Durban",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Branch{Name="Nelspruit",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Branch{Name="Johannesburg",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Branch{Name="Port Shepstone",CreatedDate=DateTime.Now,CreatedBy="System"},
        new Branch{Name="Pretoria",CreatedDate=DateTime.Now,CreatedBy="System"}
        };
        foreach (Branch b in branches)
        {
            context.Branches.Add(b);
        }
        context.SaveChanges();
    }
}

这一切似乎都可以正常工作,并且可以正常创建数据库,但是我现在想尝试创建Controller和Views

我设法用一个模型做到了,但似乎无法正确放置整个视图模型。

我的控制器

using BizDevHub.ViewModels;

public async Task<IActionResult> Index()
{
    return View(await _context.Intermediaries.ToListAsync());
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID")] Intermediaries Intermediaries)
{
    if (ModelState.IsValid)
    {
        _context.Add(Intermediaries);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(Intermediaries);
}

我的观点也是如此

我的视图

@model IEnumerable<BizDevHub.Models.Intermediary>

@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.RegisteredName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.TradingName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Registration)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.VATNumber)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FSPNumber)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.CreatedDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.CreatedBy)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.RegisteredName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TradingName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Registration)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.VATNumber)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FSPNumber)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CreatedDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CreatedBy)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.IntermediaryID">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.IntermediaryID">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.IntermediaryID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

我在做什么错了?

谢谢。

1 个答案:

答案 0 :(得分:2)

@Anonymous是正确的,您需要重新设计View模型。如果仅将实体分配为属性,就没有视图模型,视图模型的目的是将控制器和视图与数据上下文分开

public class IntermediariesViewModel
{
 public int Id { get; set; }

 public string RegisteredName { get; set; }
 public string TradingName { get; set; }
 //other properties

 IEnumerable<BranchViewModel> Branches { get; set; }
}

public class BranchViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

查看:

@model IEnumerable<BizDevHub.Models.IntermediariesViewModel>

编辑:但是如何将两个视图模型合并到一个控制器中,并使用诸如索引,编辑和删除之类的方法进行显示?

控制器:

public IActionResult Update([FromBody]IntermediariesViewModel model)
        {
            var intermediary = _context.Intermediaries.Where(x=> x.IntermediaryID == model.Id).FirstOrDefault();
            if(intermediary != null)
            {
                intermediary.RegisteredName  = model.RegisteredName ;
                //rest of updates

                _context.SaveChanges();
            }
        }


        public IActionResult Delete([FromBody]int  IntermediariesId)
        {
            var intermediary = _context.Intermediaries.Where(x=> x.IntermediaryID == IntermediariesId).FirstOrDefault();
            if(intermediary != null)
            {
                _context.Intermediaries.Remove(intermediary);               
                _context.SaveChanges();
            }
        }

查看:

@Html.DisplayNameFor(model => model.RegisteredName)

@Html.DisplayNameFor(model => model.BranchViewModel[0].Name)// first branch name, you may want to iterate