EF 3.1 Core(新手)在视图中访问一对多
EF 3.1 Core (Newbie) Access One to Many in View
我刚刚开始使用 ASP.Net Core 和 EntityFramework 在 C# 中进行开发。我在尝试弄清楚如何专门访问和保存我的地址数据时遇到了一些困难。简而言之,我的公司至少有两个地址,一个是账单地址,一个是服务地址。
我有三个模型(请注意,为了这个 post,我已经将属性配对)。
公司型号:
public int Id {get; set;}
public string Name {get; set;}
public virtual ICollection<Address> Addresses {get; set;}
地址模型:
public int Id {get; set;}
public int CompanyId {get; set;}
public string street1 {get; set;}
public AddressTypeId {get; set;
public AddressType AddressType {get; set;}
public virtual Company Company {get; set;}
地址类型模型:
public int Id {get; set;}
public string AddressType {get; set;}
我正在使用带有预先加载的 EF。我可以根据 ID 加载我的公司,我也可以显示一个 EDIT 视图 ,其中包含我公司的所有详细信息,但我不知道如何加载不同的地址(计费和服务)到视图中,以便可以编辑它们并将其提交回数据库。我只想编辑服务地址和账单地址。
我的控制器有以下代码:
CompanyDetailsViewModel companyDetailsViewModel = new CompanyDetailsViewModel();
var company = _companyRepository.GetCompanyById(id);
var addresses = company.Addresses;
Address serviceAddress = null;
Address billingAddress = null;
foreach (var address in addresses)
{
switch (address.AddressType.Display.ToLower())
{
case "service":
serviceAddress = address;
break;
case "billing":
billingAddress = address;
break;
}
}
companyDetailsViewModel.Company = company;
companyDetailsViewModel.BillingAddress = billingAddress;
companyDetailsViewModel.ServiceAddress = serviceAddress;
return View(companyDetailsViewModel);
这是我在 ViewModel 中的内容
public Company Company { get; set; }
public List<CompanyType> CompanyTypeList { get; set; }
public List<CompanySource> CompanySourceList { get; set; }
public List<State> StateList { get; set; }
public string EncodedAddress { get; set; }
public Address ServiceAddress { get; set; }
public Address BillingAddress { get; set; }
和视图的一部分
<input asp-for="@Model.Company.Name" class="form-control" />
<input asp-for="@Model.ServiceAddress.Street1" class="form-control"/>
<input asp-for="@Model.ServiceAddress.Street2" class="form-control" />
<input asp-for="@Model.ServiceAddress.City" class="form-control" />
<select asp-for="@Model.ServiceAddress.StateId" class="form-control"
asp-items="@(new SelectList(Model.StateList,"Id","StateAbbreviation"))">
</select>
<input asp-for="@Model.ServiceAddress.PostalCode" class="form-control" />
希望这是有道理的。有点难解释。
请注意,我知道为什么数据没有更新(这是因为我在 ViewModel 中为服务和帐单地址使用单独的 类)但我只是不知道如何连接那些导致这个问题的人。 :-)
非常感谢您的帮助。
--- 值
将 AddressType 更改为 Enum 并将其存储在地址模型中
public int Id {get; set;}
public int CompanyId {get; set;}
public string street1 {get; set;}
public AddressType AddressType {get; set;}
public virtual Company Company {get; set;}
public enum AddressType
{
Billing = 1,
Service = 2
}
为地址的每个循环创建并编辑它们
在Edit View上,需要用hidden control
来存储当前的Company Id
字段,否则不知道当前修改的是哪一项数据。
你应该在页面上显示所有类型的地址,然后修改相应的数据传递给控制器,然后edit the corresponding address according to the id value
。
具体可以参考下面的代码(我根据你提供的字段简化了代码,我用的是ef core)
编辑视图:
@model WebApplication_core_mvc.Controllers.CompanyDetailsViewModel
@{
ViewData["Title"] = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Edit</h1>
<form asp-action="Edit" method="post">
<input asp-for="@Model.Company.Id" class="form-control" hidden />
CompanyName: <input asp-for="@Model.Company.Name" class="form-control" />
BillingAddress: <input asp-for="@Model.BillingAddress.street1" class="form-control" />
ServiceAddress: <input asp-for="@Model.ServiceAddress.street1" class="form-control" />
<input id="Button1" type="submit" value="button" />
</form>
@*<input asp-for="@Model.ServiceAddress.Street2" class="form-control" />
<input asp-for="@Model.ServiceAddress.City" class="form-control" />
<select asp-for="@Model.ServiceAddress.StateId" class="form-control"
asp-items="@(new SelectList(Model.StateList,"Id","StateAbbreviation"))">
</select>
<input asp-for="@Model.ServiceAddress.PostalCode" class="form-control" />*@
控制器:
public class CompanyAddressController : Controller
{
private readonly MyDbContext _context;
public CompanyAddressController(MyDbContext context)
{
_context = context;
}
public IActionResult Edit(int id)
{
CompanyDetailsViewModel companyDetailsViewModel = new CompanyDetailsViewModel();
var company = _context.CompanyModel.Include(x => x.Addresses).ThenInclude(x => x.AddressType).Where(x => x.Id == id).FirstOrDefault();
var addresses = company.Addresses;
AddressModel serviceAddress = null;
AddressModel billingAddress = null;
foreach (var address in addresses)
{
switch (address.AddressType.AddressType.ToLower())
{
case "service":
serviceAddress = address;
break;
case "billing":
billingAddress = address;
break;
}
}
companyDetailsViewModel.Company = company;
companyDetailsViewModel.BillingAddress = billingAddress;
companyDetailsViewModel.ServiceAddress = serviceAddress;
return View(companyDetailsViewModel);
}
[HttpPost]
public IActionResult Edit(CompanyDetailsViewModel companyDetailsViewModel)
{
var xx = _context.CompanyModel.Include(x => x.Addresses).ThenInclude(x => x.AddressType).Where(x => x.Id == companyDetailsViewModel.Company.Id).FirstOrDefault();
foreach (var address in xx.Addresses)
{
switch (address.AddressType.AddressType.ToLower())
{
case "service":
address.street1 = companyDetailsViewModel.ServiceAddress.street1;
break;
case "billing":
address.street1 = companyDetailsViewModel.BillingAddress.street1;
break;
}
}
_context.SaveChanges();
return View();
}
}
结果如下:
我刚刚开始使用 ASP.Net Core 和 EntityFramework 在 C# 中进行开发。我在尝试弄清楚如何专门访问和保存我的地址数据时遇到了一些困难。简而言之,我的公司至少有两个地址,一个是账单地址,一个是服务地址。
我有三个模型(请注意,为了这个 post,我已经将属性配对)。
公司型号:
public int Id {get; set;}
public string Name {get; set;}
public virtual ICollection<Address> Addresses {get; set;}
地址模型:
public int Id {get; set;}
public int CompanyId {get; set;}
public string street1 {get; set;}
public AddressTypeId {get; set;
public AddressType AddressType {get; set;}
public virtual Company Company {get; set;}
地址类型模型:
public int Id {get; set;}
public string AddressType {get; set;}
我正在使用带有预先加载的 EF。我可以根据 ID 加载我的公司,我也可以显示一个 EDIT 视图 ,其中包含我公司的所有详细信息,但我不知道如何加载不同的地址(计费和服务)到视图中,以便可以编辑它们并将其提交回数据库。我只想编辑服务地址和账单地址。
我的控制器有以下代码:
CompanyDetailsViewModel companyDetailsViewModel = new CompanyDetailsViewModel();
var company = _companyRepository.GetCompanyById(id);
var addresses = company.Addresses;
Address serviceAddress = null;
Address billingAddress = null;
foreach (var address in addresses)
{
switch (address.AddressType.Display.ToLower())
{
case "service":
serviceAddress = address;
break;
case "billing":
billingAddress = address;
break;
}
}
companyDetailsViewModel.Company = company;
companyDetailsViewModel.BillingAddress = billingAddress;
companyDetailsViewModel.ServiceAddress = serviceAddress;
return View(companyDetailsViewModel);
这是我在 ViewModel 中的内容
public Company Company { get; set; }
public List<CompanyType> CompanyTypeList { get; set; }
public List<CompanySource> CompanySourceList { get; set; }
public List<State> StateList { get; set; }
public string EncodedAddress { get; set; }
public Address ServiceAddress { get; set; }
public Address BillingAddress { get; set; }
和视图的一部分
<input asp-for="@Model.Company.Name" class="form-control" />
<input asp-for="@Model.ServiceAddress.Street1" class="form-control"/>
<input asp-for="@Model.ServiceAddress.Street2" class="form-control" />
<input asp-for="@Model.ServiceAddress.City" class="form-control" />
<select asp-for="@Model.ServiceAddress.StateId" class="form-control"
asp-items="@(new SelectList(Model.StateList,"Id","StateAbbreviation"))">
</select>
<input asp-for="@Model.ServiceAddress.PostalCode" class="form-control" />
希望这是有道理的。有点难解释。
请注意,我知道为什么数据没有更新(这是因为我在 ViewModel 中为服务和帐单地址使用单独的 类)但我只是不知道如何连接那些导致这个问题的人。 :-)
非常感谢您的帮助。
--- 值
将 AddressType 更改为 Enum 并将其存储在地址模型中
public int Id {get; set;}
public int CompanyId {get; set;}
public string street1 {get; set;}
public AddressType AddressType {get; set;}
public virtual Company Company {get; set;}
public enum AddressType
{
Billing = 1,
Service = 2
}
为地址的每个循环创建并编辑它们
在Edit View上,需要用hidden control
来存储当前的Company Id
字段,否则不知道当前修改的是哪一项数据。
你应该在页面上显示所有类型的地址,然后修改相应的数据传递给控制器,然后edit the corresponding address according to the id value
。
具体可以参考下面的代码(我根据你提供的字段简化了代码,我用的是ef core)
编辑视图:
@model WebApplication_core_mvc.Controllers.CompanyDetailsViewModel
@{
ViewData["Title"] = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Edit</h1>
<form asp-action="Edit" method="post">
<input asp-for="@Model.Company.Id" class="form-control" hidden />
CompanyName: <input asp-for="@Model.Company.Name" class="form-control" />
BillingAddress: <input asp-for="@Model.BillingAddress.street1" class="form-control" />
ServiceAddress: <input asp-for="@Model.ServiceAddress.street1" class="form-control" />
<input id="Button1" type="submit" value="button" />
</form>
@*<input asp-for="@Model.ServiceAddress.Street2" class="form-control" />
<input asp-for="@Model.ServiceAddress.City" class="form-control" />
<select asp-for="@Model.ServiceAddress.StateId" class="form-control"
asp-items="@(new SelectList(Model.StateList,"Id","StateAbbreviation"))">
</select>
<input asp-for="@Model.ServiceAddress.PostalCode" class="form-control" />*@
控制器:
public class CompanyAddressController : Controller
{
private readonly MyDbContext _context;
public CompanyAddressController(MyDbContext context)
{
_context = context;
}
public IActionResult Edit(int id)
{
CompanyDetailsViewModel companyDetailsViewModel = new CompanyDetailsViewModel();
var company = _context.CompanyModel.Include(x => x.Addresses).ThenInclude(x => x.AddressType).Where(x => x.Id == id).FirstOrDefault();
var addresses = company.Addresses;
AddressModel serviceAddress = null;
AddressModel billingAddress = null;
foreach (var address in addresses)
{
switch (address.AddressType.AddressType.ToLower())
{
case "service":
serviceAddress = address;
break;
case "billing":
billingAddress = address;
break;
}
}
companyDetailsViewModel.Company = company;
companyDetailsViewModel.BillingAddress = billingAddress;
companyDetailsViewModel.ServiceAddress = serviceAddress;
return View(companyDetailsViewModel);
}
[HttpPost]
public IActionResult Edit(CompanyDetailsViewModel companyDetailsViewModel)
{
var xx = _context.CompanyModel.Include(x => x.Addresses).ThenInclude(x => x.AddressType).Where(x => x.Id == companyDetailsViewModel.Company.Id).FirstOrDefault();
foreach (var address in xx.Addresses)
{
switch (address.AddressType.AddressType.ToLower())
{
case "service":
address.street1 = companyDetailsViewModel.ServiceAddress.street1;
break;
case "billing":
address.street1 = companyDetailsViewModel.BillingAddress.street1;
break;
}
}
_context.SaveChanges();
return View();
}
}
结果如下: