EF Работа с моделями «один ко многим» с композитными клавишами - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь изучить .Net Core 2.1 и тестирую небольшой проект с уже существующей базой данных.У нас есть 3 таблицы (Template, TemplateDesc, TemplateParameter), одна из которых имеет отношение один ко многим.Когда я получаю один шаблон с контроллером, он возвращает ноль для TemplateDescription и ParameterValues.Также, если я пытаюсь удалить Шаблон, он возвращает исключение FK.Может кто-нибудь указать на проблему с приведенными ниже кодами?

Примечание. Я использую расширение Swagger для проверки кодов.

public class Template
{
    public decimal CompanyCode { get; set; }
    public string TemplateCode { get; set; }
    public List<TemplateDesc> TemplateDescriptions { get; set; }
    public DateTime TemplateDate { get; set; }
    public string RuleCode { get; set; }
    public string SourceTypeCode { get; set; }
    public string Description { get; set; }
    public bool IsBlocked { get; set; }
    public string CreatedUserName { get; set; }
    public DateTime CreatedDate { get; set; }
    public List<TemplateParameter> ParameterValues { get; set; }
}

public class TemplateDesc
{
    public decimal CompanyCode { get; set; }
    public string TemplateCode { get; set; }
    public string LangCode { get; set; }
    public string TemplateDescription { get; set; }
}

public class TemplateParameter
{
    public decimal CompanyCode { get; set; }
    public string TemplateCode { get; set; }
    public string TemplateRuleCode { get; set; }
    public string ParameterName { get; set; }
    public string ParameterValue { get; set; }
}

modelBuilder.Entity<Template>(entity =>
{
    entity.HasKey(e => new { e.CompanyCode, e.TemplateCode });
    entity.HasMany(e => e.TemplateDescriptions).WithOne(e => e.Template).HasForeignKey(e => new { e.CompanyCode, e.TemplateCode });
    entity.HasMany(e => e.ParameterValues).WithOne(e => e.Template).HasForeignKey(e => new { e.CompanyCode, e.TemplateCode });
}

modelBuilder.Entity<TemplateDesc>(entity =>
{
    entity.HasKey(e => new { e.CompanyCode, e.TemplateCode, e.LangCode });
    entity.HasOne(e => e.Template).WithMany(e => e.TemplateDescriptions).HasForeignKey(e => new { e.CompanyCode, e.TemplateCode }).OnDelete(DeleteBehavior.Cascade);
}

modelBuilder.Entity<TemplateParameter>(entity =>
{
    entity.HasKey(e => new { e.CompanyCode, e.TemplateCode, e.TemplateRuleCode, e.ParameterName});
    entity.HasOne(e => e.Template).WithMany(e => e.ParameterValues).HasForeignKey(e => new { e.CompanyCode, e.TemplateCode}).OnDelete(DeleteBehavior.Cascade);
}

[HttpGet]
public ActionResult<Template> GetWithKey([FromQuery] decimal companyCode, [FromQuery] string templateCode)
{
    try
    {
        var template = this.mRepository.Find(e => e.CompanyCode == companyCode && e.TemplateCode.AreEqual(templateCode)).FirstOrDefault();

        if (template == null)
            return new JsonResult(new ApiResponse<Template>(ResponseType.Exception, null));

        return new JsonResult(new ApiResponse<Template>(ResponseType.Success, template));
    }
    catch
    {
        throw;
    }
}

[HttpDelete]
public ActionResult DeleteWithKey([FromQuery] decimal companyCode, [FromQuery] string templateCode)
{
    if (this.mRepository.Find(e => e.CompanyCode == companyCode && e.TemplateCode.AreEqual(templateCode)).Count() < 1)
        return new JsonResult(new ApiResponse<string>(ResponseType.NotFound, templateCode));

    this.mRepository.Delete(companyCode, templateCode);
    return new JsonResult(new ApiResponse<Template>(ResponseType.Success, null));
}

1 Ответ

0 голосов
/ 03 апреля 2019

Вы должны использовать либо ленивую загрузку, либо использовать конструкцию Include:

db.Templates
    .Include(x => x.TemplateDesc)
    .Include(x => x.TemplateParameter)
    .FirstOrDefault(...)

Включения могут быть включены в метод расширения:

public IQueryable<Template> BuildTemplate(this DbSet<Template> set)
{
  return set.Include(x => x.TemplateDesc)
        .Include(x => x.TemplateParameter);
}

Тогда вы можете использовать

dbContext.Templates.BuildTemplate.FirstOrdefault(x => x.TemplateDescriptions.Any(td => td.TemplateCode == "xyz"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...