Foreach duplicating the data

Asked

Viewed 607 times

3

I possess 2 foreachs, to search for dates on ViewBags, where I return both in a select.

But for each item of the first foreach, it makes a complete loop in the second, thus doubling the values, for each item of the first.

Ex: If I have 3 items in the first foreach and 2 items in the second, my final result will be 6 items in my select, and it repeats the data, after the loop of the first.

My problem is: How to do not repeat this data?

My Foreahcs in the view:

<div class="col-md-9">
                        <select class="form-control" style="width:250px" id="selectPeriodo" name="sAquisitivo">
                            @foreach (var date in ViewBag.Ferias)
                            {
                                foreach (var fim in ViewBag.FimFerias)
                                {
                                    <option>
                                        @Convert.ToDateTime(date).ToShortDateString() à @Convert.ToDateTime(fim).ToShortDateString()
                                    </option>
                                }
                            }
                        </select>
                    </div>

My Viewbags:

 ViewBag.Ferias = funcionarioFeriasRepository.Lista.Where(r => r.CdMatricula == matricula && r.SqContrato == contrato && r.DtInicioConcessao == null)
            .Select(x => x.DtInicioPeriodo).ToList();
            ViewBag.FimFerias = funcionarioFeriasRepository.Lista.Where(r => r.CdMatricula == matricula && r.SqContrato == contrato && r.DtInicioConcessao == null)
            .Select(x => x.DtFimPeriodo).ToList();

Entity:

[DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime? dtInicioFerias { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime? dtFimFerias { get; set; }

        public string sAquisitivo { get; set; }

Upshot: Resultado atual

Remembering that I am working with Foreachs, because it was the only option I could find to format the dates to the dd/MM/yyyy format. Because they in a Dropdownlist were not formatted, even using toString() and adding annotations in the model.

2 answers

4

I believe this is what you want. I see no reason for two foreachs. This solution was given because the viewBag was created in the wrong way. So she would look like this:

ViewBag.Ferias = funcionarioFeriasRepository.Lista.Where(r => r.CdMatricula == matricula && r.SqContrato == contrato && r.DtInicioConcessao == null)
        .Select(x => new { Inicio = x.DtInicioPeriodo, Fim = x.DtFimPeriodo}).ToList();

I did the conversion there but you may not do if you need the data without conversion elsewhere. But in general it is not the right, the view must have as little processing as possible. Then the view will look like this:

<div class="col-md-9">
    <select class="form-control" style="width:250px" id="selectPeriodo" name="sAquisitivo">
        @foreach (var date in ViewBag.Ferias) {
            <option>
                @Convert.ToDateTime(date.Inicio).ToShortDateString() à @Convert.ToDateTime(date.Fim).ToShortDateString()
            </option>
        }
    </select>
</div>

I put in the Github for future reference.

I have no way to test, maybe you have to make some adaptation to work but the general idea is this.

  • I’ve tried it this way, but when I put it to Convert at Viewbag, I get this error: LINQ to Entities does not recognize the method 'System.String Toshortdatestring()' method, and this method cannot be Translated into a store Expression. I edited the question, with the entity.

  • 1

    If this is just the problem, it would just change the conversion place again, I will edit. I’m finding the whole expression strange, but if you’re saying it works, okay. Like I said, I can’t test it. I don’t understand why I should catch a guy DateTime has to be converted to DateTime. And I don’t understand why it works on view but not in the viewbag. But your problem was having two loops. This problem has been solved.

3


As posted by @Maniero, the view should have as little processing as possible, ideally you simply display the value in the view and not keep converting data etc...

Consider the code below only if you can’t implement as @Maniero suggested. But focusing on your foreach, I believe you can try to assemble these values without duplicating the dates like this:

...
@for(int i = 0; i < ViewBag.Ferias.Count(); i++)
{
   var l = 0;
   while(l < 1)
   {
      <option>
              @Convert.ToDateTime(ViewBag.Ferias[i]).ToShortDateString() à @Convert.ToDateTime(ViewBag.FimFerias[i]).ToShortDateString()
       </option>
      l++;
   }
}
...

Editing:

Removed the parentheses of ViewBag.Ferias.Count in the for.

Removed the While, I had entered it in the code above when I was reasoning about the 2 foreachs, but it is not necessary.

...
@for(int i = 0; i < ViewBag.Ferias.Count; i++)
{
      <option>
              @Convert.ToDateTime(ViewBag.Ferias[i]).ToShortDateString() à @Convert.ToDateTime(ViewBag.FimFerias[i]).ToShortDateString()
       </option>
}
...
  • I test your method, and I get this error: The 'System.Collections.Generic.List<System.Datetime? >. Count' cannot be used as a method. I’m trying to handle in control but have to display to my superiors approve the functionality, so I added in view, just for that.

  • It is probably the () of Viewbag.Ferias.Count(). Test removing the () please. If this is the problem I update the answer code.

  • 1

    That’s exactly what it was. Thanks .

  • 3

    Just a note, this while loop is unnecessary.

  • 2

    var l = 0; while(l < 1) { /**/ l++; }? I’m gonna start doing this around my code........

  • 1

    @user2363 removed the While, I had entered it into the code when I was reasoning about the 2 foreachs, but had forgotten to remove in the answer, really it is not necessary. Thanks!

  • @dcastro removed the While, I had entered it in the code above when I was reasoning about the 2 foreachs, but it is not necessary. Thanks!

  • @Renilson Andrade good that helped. I updated the answer according to his return and user2363 and dcastro collaboration.

  • 1

    I still don’t understand how this answer alone answers the question.

  • @bigown my question was for the duplicated data, because of the 2 foreachs, taking away the foreachs and adding the for( shown above), the data stopped duplicating, and are showing normally, solving the problem that had. So I marked it as an answer.

  • @bigown the values were being displayed in duplicate way right? It is possible to solve this both by adjusting according to your response (which I also quote in my reply as the best way). But, with this adjustment using "for" also solves the problem. Got it?

  • @Renilsonandrade without changing anything in viewbag?

  • Yeah, leaving it the way it was

  • 1

    It seems strange to me, but I have no way to test. Anyway generate the way this algorithm is done since the viewbag, until the view is fundamentally wrong. It can even give the result you expect but in the wrong way. This is not how you program. But it’s your decision and the damage won’t be mine.

  • @Bigown Has some problem in my answer code?

  • There is a problem in the original code, its only keeps it. It continues to treat two related expressions as if they were separate things. And yet, while it’s likely to work, nothing guarantees that the two expressions are synchronized and it’s possible to print start and end dates that are unrelated. You cannot rely on one collection to run another. It works, but this is programming by coincidence. Coincidence programming is a serious and endemic problem but only those who do not practice this form understand this.

  • Blz if my answer is ok, great! I understand and agree 100% with your comment tbm. My code focuses on solving the loop duplicity problem. Now, which is the best or most correct way to render a list in the past scenario... would be another question, where your answer fits without a shadow of a doubt.

Show 12 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.