【发布时间】:2018-07-25 20:06:52
【问题描述】:
我遇到了一个本应在 EFCore 2.1 中更正的问题。我知道这在 2.0 中是没有的。我的项目是 MVC Core 2.1 应用程序,EFCore 也是 2.1。
我在网上搜索了几种不同的表达问题的方式,但我得到的信息没有完成使代码正常工作所需的整个代码过程。
我有一个模型母亲,而母亲有一个邮寄地址和实际地址的子模型。我正在使用带有 FromSql 的存储过程,以便让我能够在我的过程中进行多个连接。存储过程在 Linq 中几乎是不可能写出来的。
我将包含我编写的符合我已经阅读的示例的所有内容。 请注意:我在代码中使用区域是因为我正在编写一个具有多个功能区域的系统。
模型 - Mother.cs
namespace Birth.Models
{
public class Mother
{
[Key]
public int MomId { get; set; }
public string MomFirst { get; set; }
public string MomLast { get; set; }
//[ForeignKey("MomId")]
public MotherAddress Physical { get; set; }
// public MotherAddress Mailing { get; set; }
}
//[Owned]
public class MotherAddress
{
public string pType { get; set; }
public string Street { get; set; }
public string PreDir { get; set; }
[Key]
public int MomId { get; set; }
public Mother Mother { get; set; }
}
}
接口 - IbirthRepository.cs
public interface IBirthRepository
{
IQueryable<Mother> Mothers { get; }
IQueryable<MotherAddress> MotherAddresses { get; }
}
存储库 - BirthRepository.cs
public class BirthRepository : IBirthRepository
{
private BirthDbContext context;
public BirthRepository(BirthDbContext ctx)
{
context = ctx;
}
public IQueryable<Mother> Mothers => context.Mothers;
public IQueryable<MotherAddress> MotherAddresses => context.MotherAddresses;
}
控制器 - GetMotherController.cs
namespace VSMaintenance.Areas.Birth.Controllers
{
[Area("Birth")]
[Route("Birth/GetMother")]
public class GetMotherController : Controller
{
private BirthDbContext context;
private IBirthRepository repository;
public GetMotherController(BirthDbContext ctx, IBirthRepository repo)
{
repository = repo;
context = ctx;
}
public IActionResult Load()
{
return View("Index");
}
[HttpPost]
public async Task<ActionResult> Retrieve(Mother mother)
{
var gbd = new GetBirthData(repository, context);
var mom = new Mother();
mom = await gbd.GetMotherData(mother.MomId);
return View("Mother", mom);
}
}
}
主视图 - Mother.cshtml
@model Birth.Models.Mother
@{
ViewData["Title"] = "Mother";
}
<h2>Mother</h2>
@Html.DisplayNameFor(model => model.MomId)
@Html.DisplayFor(model => model.MomId)
<br />
@Html.DisplayNameFor(model => model.MomFirst)
@Html.DisplayFor(model => model.MomFirst)
<br />
@Html.DisplayNameFor(model => model.MomLast)
@Html.DisplayFor(model => model.MomLast)
<br /><br /><br />
@Html.RenderPartialAsync("Birth/_MotherAddress", Model.Physical)
@*@Html.RenderPartialAsync("Birth/_MotherAddress", Model.Mailing)*@
部分视图 - MotherAddress.cshtml
@model Birth.Models.MotherAddress
<div class="container">
<div class="row">
<div class="col-sm-3">
@Html.DisplayNameFor(model => model.pType)
</div>
<div class="col-sm-3">
@Html.DisplayNameFor(model => model.Street)
</div>
<div class="col-sm-4">
@Html.DisplayNameFor(model => model.PreDir)
</div>
<div class="col-sm-2"> </div>
</div>
<div class="row">
<div class="col-sm-3">
@Html.TextBoxFor(model => model.pType, new { Style = "width:100%" })
</div>
<div class="col-sm-3">
@Html.TextBoxFor(model => model.Street, new { Style = "width:100%" })
</div>
<div class="col-sm-4">
@Html.TextBoxFor(model => model.PreDir, new { Style = "width:80%" })
</div>
<div class="col-sm-2"> </div>
</div>
</div>
Models.Data - GetBirthData.cs
namespace Birth.Models.Data
{
public class GetBirthData
{
private IBirthRepository repo;
pivate BirthDbContext _ctx;
public GetBirthData(IBirthRepository repository, BirthDbContext context)
{
repo = repository;
_ctx = context;
}
public async Task<Mother> GetMotherData(int MomId)
{
Mother list = new Mother();
try
{
string query = "exec MAINTGetMotherAddresses {0}";
list = await repo.Mothers
.FromSql(query, MomId)
.AsNoTracking()
.FirstOrDefaultAsync();
}
catch (Exception ex)
{
var msg = ex.Message;
}
return list;
}
}
}
DbContext - BirthDbContext.cs
namespace Birth.Models.Data
{
public class BirthDbContext : DbContext
{
public BirthDbContext(DbContextOptions<BirthDbContext> options)
:base(options) {
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Mother>(b =>
{
b.HasKey(e => e.MomId);
b.Property(e => e.MomId).ValueGeneratedNever();
//b.OwnsOne<MotherAddress>(e => e.Physical);
b.HasOne<MotherAddress>(e => e.Physical)
.WithOne(e => e.Mother)
.HasForeignKey<MotherAddress>(e => e.MomId);
b.ToTable("Table1");
});
}
public DbSet<Mother> Mothers { get; set; }
public DbSet<MotherAddress> MotherAddresses { get; set; }
}
}
SQLServer 存储过程 - MAINTGetMotherAddresses
ALTER PROCEDURE MAINTGetMotherAddresses
@MotherId NUMERIC(18,0)
AS
BEGIN
SELECT
CAST(md.MOTHER_DETAIL_ID AS INT) AS MomId,
md.FIRST_NAME AS MomFirst,
md.LAST_NAME AS MomLast,
'Physical' AS pType,
maP.STREET_ADDRESS AS Street,--PhysicalStreet,
maP.PRE_DIRECTION AS PreDir --PhysicalPreDir--,
--'Mailing' AS MailingType,
--maM.STREET_ADDRESS AS MailingStreet,
--maM.PRE_DIRECTION AS MailingPreDir
,CAST(@MotherId AS INT) AS PhysicalMomId
--,CAST(@MotherId AS INT) AS MailingMomId
--,CAST(@MotherId AS INT) AS MotherAddressMomId
FROM dbo.MOTHER_DETAIL md
JOIN dbo.MOTHER_ADDRESS maP
ON maP.MOTHER_DETAIL_ID = md.MOTHER_DETAIL_ID
JOIN dbo.MOTHER_ADDRESS maM
ON maM.MOTHER_DETAIL_ID = md.MOTHER_DETAIL_ID
WHERE md.MOTHER_DETAIL_ID = @MotherId
AND maP.ADDRESS_TYPE in (133, 176)
AND maM.ADDRESS_TYPE IN (132, 175)
END
Mother_Detail 和 Mother_Address 表的字段比我在这里列出的要多得多,所以我不打算展示完整的表结构。如果您创建表并将地址添加到 Mother_Address 表,Address_Type 为 176,那么您将能够看到我当前尝试使用的结果集。我的愿望是再次加入该地址,如存储过程中所见,并在一个结果集中返回邮件和物理地址,并让系统使用这两个地址适当地填充 MotherAddress 模型。
请帮忙!这很令人沮丧。
兰迪
【问题讨论】:
标签: c# stored-procedures ef-core-2.1