0

I have an MVC application which searchs in a database for lists of entries. Sometimes there are so many that I can´t show them in my Browser so I want to show only the Top100 and if needed export all of them in a csv File to open them in Excel.

That works quite well in most cases but now I have a problem that there are more entries then my System can handle and I get an OutOfMemoryException.

My Problem now is that I want to show the user of my program that there are to many entries and it can´t open them in a file but my Method has an return value of FileStreamResult. How can I show the user an explanation of the error in the view/browser? Or do you know a better solution to handle the OutOfMemoryException?

Here is the Method which throws the Exetption. It happens in the fourth line "artikel.ToList();":

public FileStreamResult DownloadCSV(string agraCd, string agrCd)
    {
        using (var entities = new RS2_XENTESTEntities())
        {
            var artikel = Select(entities, agraCd, agrCd);

            var artikelliste = artikel.ToList();

            MemoryStream output = new MemoryStream();
            StreamWriter writer = new StreamWriter(output, Encoding.UTF8);
            writer.Write("Artikelnummer;");
            writer.Write("Kurzbezeichnung;");
            writer.Write("Bezeichnung1;");
            writer.Write("Status;");
            writer.Write("Einheit;");
            writer.Write("Notiz");
            writer.WriteLine();
            foreach (var order in artikelliste)
            {
                //Artikelnummer – Art_nr
                writer.Write(order.ART_NR + ";");
                //Kurzbezeichnung – Art_kbez
                writer.Write(order.ART_KBEZ + ";");
                //Bezeichnung 1 – Art_bez1
                writer.Write(order.ART_BEZ1 + ";");
                //Status – Art_status
                writer.Write(order.ART_STATUS + ";");
                //Einheit – Meh_cd
                writer.Write(order.MEH_CD + ";");
                //Notiz – Art_notiz
                if (order.ART_NOTIZ != null)
                {
                    order.ART_NOTIZ = order.ART_NOTIZ.Replace(System.Environment.NewLine, " ");
                }
                writer.Write(order.ART_NOTIZ);

                writer.WriteLine();
            }

            writer.Flush();
            output.Position = 0;


            return File(output, "text/csv", "Export.csv");
        }
    }

1 Answer 1

2

Edit: Oh didn't saw your output is an MemoryStream... Maybe you can return some kind of (Http)Response where you can write to the Output.

Your OOM Exception will raise at line

var artikelliste = artikel.ToList();

... because the .ToList() will actually call your repository and get each object into memory. I dont know your select method but I assume, that it returns an IEnumerable or some kind of reader? You can just use this reader or IEnumerable (dont call ToList()) and it could work (depending on your Select implementation).

Sign up to request clarification or add additional context in comments.

5 Comments

Is MemoryStream bad? Or is there a better solution? My Select returns an IQueryable.
In general its not bad but it sits in your memory and you get an OoM exception ;-) OK if Select returns an IQueryable you can iterate over it without calling ToList();
Do you know a better solution than MemoryStream? Because when I remove the ToList() it stops working in the foreachloop because he has to resolve the query somewhere.
I guess at the end of the day if you have enough data you are going to run out of memory. one solution might be to change to a file writer, (lose the ToList as suggested) but then you will have to give the user some way of downloading the resultant file (presumably we are talking gigabytes?)
Hm maybe not Gigabytes, I don´t really know exactly. I´ve already tried to replace the MemoryStream with a FileStream. And he writes data into the File for some time but than crashes too in the foreachloop...

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.