简体   繁体   中英

What's the best way to retrieve data from 2 tables for filling a list of objects that has another list of objects inside it in C#?

Let's say i have an Invoice and an Item class defined as:

class Invoice
{ 
    string ID { get; set; }
    string Date { get; set; }
    int ReceiptNumber { get; set; }
    string TotalValueOfSale { get; set; }
    List<Item> Items { get; set; }
}

class Item
{
    string Description { get; set; }
    string SalePrice { get; set; }
    string Quantity { get; set; }
}

And a SQLite database with 2 tables related to each other by an ID colum:

CREATE TABLE Invoices
(
    ID                   VARCHAR      PRIMARY KEY
                                      NOT NULL
                                      UNIQUE,
    Date                 DATETIME     NOT NULL,
    ReceiptNumber        INT          NOT NULL,
    TotalValueOfSale     VARCHAR      NOT NULL,
);

CREATE TABLE Items 
(
    RelatedInvoiceID     VARCHAR NOT NULL
                                 REFERENCES Invoices(ID) ON DELETE CASCADE,
    Description          VARCHAR NOT NULL,
    SalePrice            VARCHAR NOT NULL,
    Quantity             VARCHAR NOT NULL,
);

Which will be the best way to get a list of Invoices by date from the database without putting to much load on it?

I've been thinking in doing just 1 query such as:

SELECT
    T1.ID, T1.Date, T1.ReceiptNumber, T1.TotalValueOfSale,
    T2.Description, T2.SalePrice, T2.Quantity
FROM
    Invoices T1
INNER JOIN
    Items T2
ON
    T1.ID = T2.RelatedInvoiceID
WHERE
    T1.Date = YYYY-MM-DD

, and process the result in C# but that seems like a pain to do. I know the easy way would be to first query the invoice objects without items and later take the ID of each one and query their respective items, but i don't want to do all those queries for say...a list a 200 invoices with N items each one.

Any ideas or suggestion would be of great help!

are you using entity framework? That's one line of code:

context.invoices.where(i => i.date == yourdate).include(t => t.items).tolist();

For future reference, i ended up doing this (i know, i know the inital question was with dates but this follows the same principle):

class Item
{
    string RelatedInvoiceID { get; set; }
    string Description { get; set; }
    string SalePrice { get; set; }
    string Quantity { get; set; }
}

List<Invoice> ReadInvoiceRegistries(int initialInvoiceNumber, int finalInvoiceNumber)
{
    try
    {
        List<Invoice> readInvoices = new List<Invoice>();
        List<Item> AllReadItems = new List<Item>();

        using (SQLiteConnection sqliteConnection = new SQLiteConnection(connectionString ))
        {
            sqliteConnection.Open();

            string getInvoicesQuery =
                "SELECT " +
                    "T1.ID, T1.Date, T1.ReceiptNumber, T1.TotalValueOfSale," +
                    "T2.RelatedInvoiceID, T2.Description, T2.SalePrice,T2.Quantity " +
                "FROM " +
                    "Invoices T1 " +
                "INNER JOIN " +
                    "Items T2 " +
                "ON " +
                    "T1.ID = T2.RelatedInvoiceID " +
                "WHERE " +
                    $"T1.ReceiptNumber >= {initialInvoiceNumber} " +
                    $"AND T1.ReceiptNumber <= {finalInvoiceNumber};";

            using (SQLiteCommand sqlLiteCommand = new SQLiteCommand(getInvoicesQuery, sqliteConnection))
            {
                sqlLiteCommand.CommandType = System.Data.CommandType.Text;
                sqlLiteCommand.CommandTimeout = ExecutionTimeout;

                using (SQLiteDataReader sqLiteDataReader = sqlLiteCommand.ExecuteReader())
                {
                    while (sqLiteDataReader.Read())
                    {
                        Invoice readInvoice = new Invoice(InvoiceType);
                        Item readItem = new Item();

                        for (int column = 0; column < sqLiteDataReader.FieldCount; column++)
                        {
                            ReadInvoiceBasicData(column, sqLiteDataReader,ref readInvoice); //Save invoice basic data related columns in Invoice object
                            ReadInvoiceItem(column, sqLiteDataReader, ref readItem); //Save items columns in Item object
                        }

                        readInvoices.Add(readInvoice);
                        AllReadItems.Add(readItem);
                    }

                    sqLiteDataReader.Close();
                }
            }

            sqliteConnection.Close();
        }

        readInvoices = readInvoices.Distinct().ToList();

        foreach(Invoice Invoice in readInvoices)
        {
            Invoice.Items = AllReadItems.Where(i=>i.RelatedInvoiceID == Invoice.TransactionID).ToList();
        }

        return readInvoices;
    }
    catch(Exception e)
    {
        return null;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM