c# Razor Pages, EF Core, Cómo puedo generar y añadir Child Records a través del Código a un Registro de Padres que aún no se ha añadido utilizando
Estoy usando C# Razor Pages con EF Core 5. No estoy usando MVC en absoluto. Estoy tratando de generar automáticamente registros infantiles (meses del año) para un registro de padres (Año con Fecha de inicio/Fecha de inicio). Mi modelo tiene las relaciones establecidas en ellos:
namespace Seasons.Models
{
public class AccountYears //Parent Record
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid AccountYearsID { get; set; }
[Display(Name = "Accounts Year Name"), Required]
public string AccountYearsName { get; set; }
[Display(Name = "Start Date"), Required, DataType(DataType.Date)]
public DateTime DateStart { get; set; }
[Display(Name = "End Date"), Required, DataType(DataType.Date)]
public DateTime DateEnd { get; set; }
//AccountYearsMonths
public List AccountYearsMonths { get; set; }
}
}
namespace Seasons.Models // Child Records
{
public class AccountYearsMonths
{
// [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid AccountYearsMonthsID { get; set; }
[Required]
public Guid AccountYearsID { get; set; }
[Display(Name = "Month Name"), Required]
public string AccountYearsMonthsName { get; set; }
[Display(Name = "Start Date"), Required, DataType(DataType.Date)]
public DateTime DateStart { get; set; }
[Display(Name = "End Date"), Required, DataType(DataType.Date)]
public DateTime DateEnd { get; set; }
//AccountsYears
public AccountYears AccountYears { get; set; }
}
Y luego mi cuentaAños de crear página - Tenga en cuenta que la página sólo tiene campos para que el padre se complete cuando creo, estoy deseando generar todos los registros infantiles en el código y guardar toda la transacción en una sola pasada.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using MyApplication.Data;
using Seasons.Models;
namespace Seasons.Areas.Setup.Pages.FinanceAccountYears
{
public class CreateModel : PageModel
{
private readonly MyApplication.Data.ApplicationDbContext _context;
public CreateModel(MyApplication.Data.ApplicationDbContext context)
{
_context = context;
// _context.Attach(AccountYearsMonths);
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public AccountYears AccountYears { get; set; }
public List AccountYearsMonths { get; set; }
// public List AccountYearsMonths { get; set; }
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
//AccYearsMonths();
//var emptyAccountYears = new AccountYears();
//if (await TryUpdateModelAsync(
// emptyAccountYears,
// "AccYears",
// ay => ay.AccountYearsID, ay => ay.AccountYearsName, ay => ay.DateStart, ay => ay.DateEnd, ay => ay.Status))
//{
// _context.AccountYears.Add(emptyAccountYears);
AccYearsMonths();
_context.AccountYears.Add(AccountYears);
await _context.SaveChangesAsync();
//Guid AddedID = AccountYears.AccountYearsID;
//AccYearsMonths(AddedID);
//_context.AccountYears.Update(AccountYears);
//await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
public void AccYearsMonths()
{
// AccountYearsMonths = new List();
DateTime MasterStartDate = AccountYears.DateStart;
DateTime MasterEndDate = AccountYears.DateEnd;
// Get the StartDate, MonthEndDate, and YearEndDate into variables
DateTime Date1 = new DateTime(MasterStartDate.Year, MasterStartDate.Month, 01);
DateTime Date2 = new DateTime(Date1.Year, Date1.Month, DateTime.DaysInMonth(Date1.Year, Date1.Month));
string MonthName = new string(Date1.ToString("MMM"));
while (Date1 < MasterEndDate)
{
AccountYears.AccountYearsMonths.Add(new AccountYearsMonths
{
AccountYearsMonthsName = MonthName,
DateStart = Date1,
DateEnd = Date2,
Status = "OPEN"
});
//AccountYearsMonths d = new AccountYearsMonths
//{
// AccountYearsMonthsName = MonthName,
// DateStart = Date1,
// DateEnd = Date2,
// Status = "OPEN",
// AccountYearsID = YearID
//};
// _context.AccountYearsMonths.Add(d);
// AccountYearsMonths.Add(d);
if (Date1.Month > 11)
{
Date1 = new DateTime(Date1.Year + 1, 01, 01);
}
else
{
Date1 = new DateTime(Date1.Year, Date1.Month + 1, 01);
} // Endif
Date2 = new DateTime(Date1.Year, Date1.Month, DateTime.DaysInMonth(Date1.Year, Date1.Month));
MonthName = Date1.ToString("MMM");
} // End While
} //End AccYearMonths
}
}
Tengo el siguiente error cuando ejecuto este código: System.NullReference Excepción: "La referencia objetiva no se establece en una instancia de un objeto". Lo que ocurre cuando se ejecuta esta línea: AccountYears.AccountYearsMonths.Add(new AccountYearsMonths
Como puedes ver por todo el código comentado he probado algunas maneras diferentes.
Cualquier ayuda sería muy apreciada.
Pregunta hecha hace 3 años, 5 meses, 5 días - Por codemasterx
3 Respuestas:
-
Necesitas inicializar
AccountYearsMonths
objeto como abajo:while (Date1 < MasterEndDate) { //change here... AccountYears.AccountYearsMonths = new List
(); AccountYears.AccountYearsMonths.Add(new AccountYearsMonths { AccountYearsMonthsName = MonthName, DateStart = Date1, DateEnd = Date2, Status = "OPEN" }); //.... } Resultado:
Respondida el Dec 17, 2020 a las 22:57 - por webweaverx
Votos positivos: 0 | Votos negativos: 0 -
El error "NullReference Exception" indica que estás intentando acceder a una referencia de un objeto que no ha sido inicializada. En este caso, en el método
AccYearsMonths()
, el error se produce en la línea donde intentas agregar un nuevoAccountYearsMonths
a la listaAccountYears.AccountYearsMonths
.La razón de este error es que la propiedad
AccountYearsMonths
de la claseAccountYears
no ha sido inicializada antes de intentar agregar elementos a ella. Para solucionar este problema, necesitas inicializar la lista antes de agregar elementos. Puedes hacerlo de la siguiente manera:csharp public void AccYearsMonths() { AccountYears.AccountYearsMonths = new List
(); // Inicializa la lista antes de agregar elementos DateTime MasterStartDate = AccountYears.DateStart; DateTime MasterEndDate = AccountYears.DateEnd; DateTime Date1 = new DateTime(MasterStartDate.Year, MasterStartDate.Month, 01); DateTime Date2 = new DateTime(Date1.Year, Date1.Month, DateTime.DaysInMonth(Date1.Year, Date1.Month)); string MonthName = new string(Date1.ToString("MMM")); while (Date1 < MasterEndDate) { AccountYears.AccountYearsMonths.Add(new AccountYearsMonths { AccountYearsMonthsName = MonthName, DateStart = Date1, DateEnd = Date2, Status = "OPEN" }); if (Date1.Month > 11) { Date1 = new DateTime(Date1.Year + 1, 01, 01); } else { Date1 = new DateTime(Date1.Year, Date1.Month + 1, 01); } Date2 = new DateTime(Date1.Year, Date1.Month, DateTime.DaysInMonth(Date1.Year, Date1.Month)); MonthName = Date1.ToString("MMM"); } } Al agregar
AccountYears.AccountYearsMonths = new List<AccountYearsMonths>();
al principio del método, te aseguras de que la lista esté inicializada antes de intentar agregar elementos a ella, lo que debería evitar el error de "NullReference Exception".Espero que esta solución te ayude a corregir el error y que puedas continuar con el desarrollo de tu aplicación. ¡Déjame saber si necesitas más ayuda!
Respondida el Dec 18, 2020 a las 22:56 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error
System.NullReferenceException
ocurre porque la propiedadAccountYearsMonths
esnull
cuando intentas añadir nuevos registrosAccountYearsMonths
a ella. Esto puede suceder si no has inicializado la propiedadAccountYearsMonths
antes de intentar añadirle elementos.Para solucionar este problema, debes inicializar la propiedad
AccountYearsMonths
como una nueva lista antes de intentar añadirle elementos. Puedes hacerlo añadiendo el siguiente código al principio del métodoAccYearsMonths()
:c
AccountYears.AccountYearsMonths = new List
(); Esto creará una nueva lista vacía para la propiedad
AccountYearsMonths
y permitirá que se añadan nuevos elementos sin errores.Aquí tienes el método
AccYearsMonths()
actualizado con la inicialización añadida:c
public void AccYearsMonths()
{ AccountYears.AccountYearsMonths = new List(); DateTime MasterStartDate = AccountYears.DateStart; DateTime MasterEndDate = AccountYears.DateEnd; // Get the StartDate, MonthEndDate, and YearEndDate into variables DateTime Date1 = new DateTime(MasterStartDate.Year, MasterStartDate.Month, 01); DateTime Date2 = new DateTime(Date1.Year, Date1.Month, DateTime.DaysInMonth(Date1.Year, Date1.Month)); string MonthName = new string(Date1.ToString("MMM")); while (Date1 < MasterEndDate) { AccountYears.AccountYearsMonths.Add(new AccountYearsMonths { AccountYearsMonthsName = MonthName, DateStart = Date1, DateEnd = Date2, Status = "OPEN" }); //AccountYearsMonths d = new AccountYearsMonths //{ // AccountYearsMonthsName = MonthName, // DateStart = Date1, // DateEnd = Date2, // Status = "OPEN", // AccountYearsID = YearID //}; // _context.AccountYearsMonths.Add(d); // AccountYearsMonths.Add(d); if (Date1.Month > 11) { Date1 = new DateTime(Date1.Year + 1, 01, 01); } else { Date1 = new DateTime(Date1.Year, Date1.Month + 1, 01); } // Endif Date2 = new DateTime(Date1.Year, Date1.Month, DateTime.DaysInMonth(Date1.Year, Date1.Month)); MonthName = Date1.ToString("MMM"); } // End While } //End AccYearMonths También es importante asegurarte de que estás utilizando el contexto de base de datos correcto para guardar los cambios. En tu código, estás utilizando
_context.AccountYears
para añadir el registroAccountYears
, pero no estás guardando los cambios en la base de datos. Para guardar los cambios, debes llamar aSaveChangesAsync()
en el contexto después de añadir el registro.Aquí tienes el método
OnPostAsync()
actualizado con la llamada aSaveChangesAsync()
:c
public async Task
{ if (!ModelState.IsValid) { return Page(); } AccYearsMonths(); _context.AccountYears.Add(AccountYears); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }OnPostAsync() Con estos cambios, tu código debería poder generar y añadir registros
AccountYearsMonths
a un registroAccountYears
que aún no se ha añadido utilizando el código, y guardar todos los cambios en una sola pasada.Respondida el Dec 18, 2020 a las 23:00 - por Gemini
Votos positivos: 0 | Votos negativos: 0