1
\$\begingroup\$

I am trying to store multiple lists to a database but I'm struggling on finding a better way of doing it, as the way I am doing it now, seems to be incorrect.

On my form, I have 6 different legs. Each leg consists of Cargo Weight, Bag Weight, Fuel Weight, and more.

Right now I am storing all the data to a new class called FlightDetails, where that class just has properties, no methods. For each leg, I am having to re-set all the property details, but for a different leg as seen below:

        private void InsertLeg1()
    {
        List<FlightDetails> leg1 = new List<FlightDetails>();
        leg1.Add(new FlightDetails
        {
            Date = dateTimeLoadPlanner.Value.Date,
            FlightNumber = cbFlightNumber.Text,
            LegNumber = 1,
            PassengerWeight = Convert.ToInt32(tbPax_L1.Text),
            BagWeight = Convert.ToInt32(tbBags_L1.Text),
            CargoWeight = Convert.ToInt32(tbCargo_L1.Text),
            Equipment = Convert.ToInt32(tbEquip_L1.Text),
            AWI = Convert.ToInt32(tbAWI_L1.Text),
            Fuel = Convert.ToInt32(tbFuel_L1.Text),
            Contigency = Convert.ToInt32(tbCont_L1.Text),
            TaxiBurn = Convert.ToInt32(tbTaxiBurn_L1.Text),
            TakeOffWeight = Convert.ToInt32(tbMTOW_L1.Text),
            LandingWeight = Convert.ToInt32(tbLandingWT_L1.Text),
            PassengerNumber = Convert.ToInt32(tbPaxNo_L1.Text),
            Seatpacks = Convert.ToInt32(tbSeatpacks_L1.Text),
            Aircraft = cbAircraft.Text,
            AircraftType = cbAircarftType.Text,
            Crew = cbCrew.Text,
            Notes = tbNotesALC.Text,
            AircraftWeight = Convert.ToInt32(tbAircraftWeight.Text),
            FuelBurn = Convert.ToInt32(tbFuelBurn_L1.Text),
            AircraftConfiguration = tbSeats_L1.Text
        });

        SaveDataALC.SaveLeg(leg1);
    }

    private void InsertLeg2()
    {
        List<FlightDetails> leg2 = new List<FlightDetails>();
        leg2.Add(new FlightDetails
        {
            Date = dateTimeLoadPlanner.Value.Date,
            FlightNumber = cbFlightNumber.Text,
            LegNumber = 2,
            PassengerWeight = Convert.ToInt32(tbPax_L2.Text),
            BagWeight = Convert.ToInt32(tbBags_L2.Text),
            CargoWeight = Convert.ToInt32(tbCargo_L2.Text),
            Equipment = Convert.ToInt32(tbEquip_L2.Text),
            AWI = Convert.ToInt32(tbAWI_L2.Text),
            Fuel = Convert.ToInt32(tbFuel_L2.Text),
            Contigency = Convert.ToInt32(tbCont_L2.Text),
            TaxiBurn = Convert.ToInt32(tbTaxiBurn_L2.Text),
            TakeOffWeight = Convert.ToInt32(tbMTOW_L2.Text),
            LandingWeight = Convert.ToInt32(tbLandingWT_L2.Text),
            PassengerNumber = Convert.ToInt32(tbPaxNo_L2.Text),
            Seatpacks = Convert.ToInt32(tbSeatpacks_L2.Text),
            Aircraft = cbAircraft.Text,
            AircraftType = cbAircarftType.Text,
            Crew = cbCrew.Text,
            Notes = tbNotesALC.Text,
            AircraftWeight = Convert.ToInt32(tbAircraftWeight.Text),
            FuelBurn = Convert.ToInt32(tbFuelBurn_L2.Text),
            AircraftConfiguration = tbSeats_L2.Text
        });

        SaveDataALC.SaveLeg(leg2);
    }


    public void InsertLeg3()
    {
        List<FlightDetails> leg3 = new List<FlightDetails>();
        leg3.Add(new FlightDetails
        {
            Date = dateTimeLoadPlanner.Value.Date,
            FlightNumber = cbFlightNumber.Text,
            LegNumber = 3,
            PassengerWeight = Convert.ToInt32(tbPax_L3.Text),
            BagWeight = Convert.ToInt32(tbBags_L3.Text),
            CargoWeight = Convert.ToInt32(tbCargo_L3.Text),
            Equipment = Convert.ToInt32(tbEquip_L3.Text),
            AWI = Convert.ToInt32(tbAWI_L3.Text),
            Fuel = Convert.ToInt32(tbFuel_L3.Text),
            Contigency = Convert.ToInt32(tbCont_L3.Text),
            TaxiBurn = Convert.ToInt32(tbTaxiBurn_L3.Text),
            TakeOffWeight = Convert.ToInt32(tbMTOW_L3.Text),
            LandingWeight = Convert.ToInt32(tbLandingWT_L3.Text),
            PassengerNumber = Convert.ToInt32(tbPaxNo_L3.Text),
            Seatpacks = Convert.ToInt32(tbSeatpacks_L3.Text),
            Aircraft = cbAircraft.Text,
            AircraftType = cbAircarftType.Text,
            Crew = cbCrew.Text,
            Notes = tbNotesALC.Text,
            AircraftWeight = Convert.ToInt32(tbAircraftWeight.Text),
            FuelBurn = Convert.ToInt32(tbFuelBurn_L3.Text),
            AircraftConfiguration = tbSeats_L3.Text
        });

        SaveDataALC.SaveLeg(leg3);
    }

Once that information is passed, I am storing it in the database here:

public static void SaveLeg(List<FlightDetails> legDetails)
    {
        using (SqlConnection conn = new SqlConnection(ConnectionLoader.ConnectionString("Threshold")))
        {
            foreach (var legDetail in legDetails)
            {
                conn.Open();
                SqlCommand saveData = new SqlCommand("Save_Leg_Loadplanner", conn);
                saveData.CommandType = CommandType.StoredProcedure;
                saveData.Parameters.AddWithValue("@DateID", legDetail.Date);
                saveData.Parameters.AddWithValue("@FlightNumber", legDetail.FlightNumber);
                saveData.Parameters.AddWithValue("@LegNumber", legDetail.LegNumber);
                saveData.Parameters.AddWithValue("@PassengerWeight", legDetail.PassengerWeight);
                saveData.Parameters.AddWithValue("@BagWeight", legDetail.BagWeight);
                saveData.Parameters.AddWithValue("@CargoWeight", legDetail.CargoWeight);
                saveData.Parameters.AddWithValue("@Equipment", legDetail.Equipment);
                saveData.Parameters.AddWithValue("@AWI", legDetail.AWI);
                saveData.Parameters.AddWithValue("@Fuel", legDetail.Fuel);
                saveData.Parameters.AddWithValue("@TaxiBurn", legDetail.TaxiBurn);
                saveData.Parameters.AddWithValue("@Contigency", legDetail.Contigency);
                saveData.Parameters.AddWithValue("@TakeOffWeight", legDetail.TakeOffWeight);
                saveData.Parameters.AddWithValue("@LandingWeight", legDetail.LandingWeight);
                saveData.Parameters.AddWithValue("@PassengerNumber", legDetail.PassengerNumber);
                saveData.Parameters.AddWithValue("@Seatpacks", legDetail.Seatpacks);
                saveData.Parameters.AddWithValue("@Aircraft", legDetail.Aircraft);
                saveData.Parameters.AddWithValue("@Notes", legDetail.Notes);
                saveData.Parameters.AddWithValue("@Crew", legDetail.Crew);
                saveData.Parameters.AddWithValue("@AircraftType", legDetail.AircraftType);
                saveData.Parameters.AddWithValue("@AircraftWeight", legDetail.AircraftWeight);
                saveData.Parameters.AddWithValue("@FuelBurn", legDetail.FuelBurn);
                saveData.Parameters.AddWithValue("@AircraftConfiguration", legDetail.AircraftConfiguration);
                saveData.ExecuteNonQuery();
            }
        }
    }

I'm not sure if there is a better way of doing this. This does work, but I feel there may be a more cleaner way of doing this.

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

Quick remarks:

  • Why do you use a stored proc? Why not use an ORM like EntityFramework, or even Dapper?

  • Use descriptive names. leg1 doesn't gain you anything.

  • Don't copy-paste, only to change a few names. InsertLeg1, InsertLeg2 and InsertLeg3 should really be a single method, but I fear your design makes this too hard. It's been far too long since I've used WinForms, but it should be possible to have a reusable "sub form" that contains all those controls, that way you could have a single method that receives this "sub form" to convert it into a FlightDetails.

  • I don't like the class name FlightDetails (not in the least because it is a plural), but I cannot think of a better one.

\$\endgroup\$
1
\$\begingroup\$

InsertLeg{X}

  • I would suggest to extract the common parts into dedicated methods
  • First let's start with the Collection initilization and Save method call
private void InsertLeg(FlightDetails leg)
    => SaveDataALC.SaveLeg(new List<FlightDetails> { leg });
  • Then let's continue with those properties where the data source is the same for all three cases
FlightDetails CreateDetails()
    => new FlightDetails
    {
        Date = dateTimeLoadPlanner.Value.Date,
        FlightNumber = cbFlightNumber.Text,
        Aircraft = cbAircraft.Text,
        AircraftType = cbAircarftType.Text,
        Crew = cbCrew.Text,
        Notes = tbNotesALC.Text,
    };
  • And finally introduce a helper method to retrieve Text property of a TextBox as an integer
int GetTextAsInteger(TextBox tb)
    => Convert.ToInt32(tb.Text);
  • Please bear in mind that this code is error-prone

After all these modifications the InsertLeg{x} could be rewritten like this

void InsertLeg1()
{
    var details = CreateDetails();
    details.LegNumber = 1;
    details.PassengerWeight = GetTextAsInteger(tbPax_L1);
    details.BagWeight = GetTextAsInteger(tbBags_L1);
    details.CargoWeight = GetTextAsInteger(tbCargo_L1);
    details.Equipment = GetTextAsInteger(tbEquip_L1);
    details.AWI = GetTextAsInteger(tbAWI_L1);
    details.Fuel = GetTextAsInteger(tbFuel_L1);
    details.Contigency = GetTextAsInteger(tbCont_L1);
    details.TaxiBurn = GetTextAsInteger(tbTaxiBurn_L1);
    details.TakeOffWeight = GetTextAsInteger(tbMTOW_L1);
    details.LandingWeight = GetTextAsInteger(tbLandingWT_L1);
    details.PassengerNumber = GetTextAsInteger(tbPaxNo_L1);
    details.Seatpacks = GetTextAsInteger(tbSeatpacks_L1);
    details.AircraftWeight = GetTextAsInteger(tbAircraftWeight);
    details.FuelBurn = GetTextAsInteger(tbFuelBurn_L1);
    details.AircraftConfiguration = tbSeats_L1.Text;
    InsertLeg(details);
}

SaveLeg

  • I think it is enough to call only once the conn.Open
    • You do not have to do that for each element in your collection
  • Rather than using AddWithValue you can use the AddRange command
saveData.Parameters.AddRange(new[]
{
    new SqlParameter("@DateID", legDetail.Date),
    new SqlParameter("@FlightNumber", legDetail.FlightNumber),
    new SqlParameter("@LegNumber", legDetail.LegNumber),
    new SqlParameter("@PassengerWeight", legDetail.PassengerWeight),
    new SqlParameter("@BagWeight", legDetail.BagWeight),
    new SqlParameter("@CargoWeight", legDetail.CargoWeight),
    new SqlParameter("@Equipment", legDetail.Equipment),
    new SqlParameter("@AWI", legDetail.AWI),
    new SqlParameter("@Fuel", legDetail.Fuel),
    new SqlParameter("@TaxiBurn", legDetail.TaxiBurn),
    new SqlParameter("@Contigency", legDetail.Contigency),
    new SqlParameter("@TakeOffWeight", legDetail.TakeOffWeight),
    new SqlParameter("@LandingWeight", legDetail.LandingWeight),
    new SqlParameter("@PassengerNumber", legDetail.PassengerNumber),
    new SqlParameter("@Seatpacks", legDetail.Seatpacks),
    new SqlParameter("@Aircraft", legDetail.Aircraft),
    new SqlParameter("@Notes", legDetail.Notes),
    new SqlParameter("@Crew", legDetail.Crew),
    new SqlParameter("@AircraftType", legDetail.AircraftType),
    new SqlParameter("@AircraftWeight", legDetail.AircraftWeight),
    new SqlParameter("@FuelBurn", legDetail.FuelBurn),
    new SqlParameter("@AircraftConfiguration", legDetail.AircraftConfiguration)
});
\$\endgroup\$
1
\$\begingroup\$

InsertLeg1, InsertLeg2, InsertLeg3 ..etc. I don't see why they're saving a single instance of FlightDetails to a list? So SaveDataALC.SaveLeg will process a List<FlightDetails> with only one element inside it. if there are multiple instances of FlightDetails then you propabaly need to store them all in one List<FlightDetails> then pass that list to SaveDataALC.SaveLeg once.

So, to make the story short, you might need to declare a global List<FlightDetails> and use it accross the class, and when you need to insert the values, just call the insert method once.

example :

public class ExampleClass
{
    private List<FlightDetails> _flightDetails = new List<FlightDetails>(); 
    
    public void SomeMethod() {
        var flightLeg = new FlightDetails {
            Date = dateTimeLoadPlanner.Value.Date,
            FlightNumber = cbFlightNumber.Text,
            LegNumber = 1,
            PassengerWeight = Convert.ToInt32(tbPax_L1.Text),
            BagWeight = Convert.ToInt32(tbBags_L1.Text),
            CargoWeight = Convert.ToInt32(tbCargo_L1.Text),
            Equipment = Convert.ToInt32(tbEquip_L1.Text),
            AWI = Convert.ToInt32(tbAWI_L1.Text),
            Fuel = Convert.ToInt32(tbFuel_L1.Text),
            Contigency = Convert.ToInt32(tbCont_L1.Text),
            TaxiBurn = Convert.ToInt32(tbTaxiBurn_L1.Text),
            TakeOffWeight = Convert.ToInt32(tbMTOW_L1.Text),
            LandingWeight = Convert.ToInt32(tbLandingWT_L1.Text),
            PassengerNumber = Convert.ToInt32(tbPaxNo_L1.Text),
            Seatpacks = Convert.ToInt32(tbSeatpacks_L1.Text),
            Aircraft = cbAircraft.Text,
            AircraftType = cbAircarftType.Text,
            Crew = cbCrew.Text,
            Notes = tbNotesALC.Text,
            AircraftWeight = Convert.ToInt32(tbAircraftWeight.Text),
            FuelBurn = Convert.ToInt32(tbFuelBurn_L1.Text),
            AircraftConfiguration = tbSeats_L1.Text
        };
        
        _flightDetails.Add(flightLeg);
    }
        
    private void InsertLegs() {
        SaveDataALC.SaveLeg(_flightDetails);    
        // if you want to reuse it then you can clear the list
        // by uncommenting the following line.
        // _flightDetails.Clear();
    }
}

The SomeMethod is just shows that you need to use _flightDetails for adding new FlightDetails in all related methods within the class.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.