Method behaves differently when called from Create and Update Controller methods

Topics: General
Sep 22, 2012 at 12:32 AM

I have a REALLY strange situation happening that I'm hoping maybe someone can help me understand.

I have 2 methods in my controller, a Create method and an Update method. Before calling the View, both of these methods create a SelectList and pass it in a ViewData item.

Create method

ViewData["reportoptionvalues"] = new SelectList(_reportoptionvaluesService.GetForRule(reportId, optionId), "Id", "Name");

Update method

ViewData["reportoptionvalues"] = new SelectList(_reportoptionvaluesService.GetForRule(optionrule.Report.Id, optionrule.Option.Id), "Id", "Name");

both methods pass 1, 1 as the two values...I just derive them differently in the Methods. Debug verified that both were passing 1, 1. Here is the Service method being called to generate the SelectList

        public IEnumerable<OptionRecord> GetForRule(int reportId, int optionId) {
            IEnumerable<OptionRecord> options = from x in _reportoptionvaluesRepository.Table
                                                where x.Report.Id == reportId && x.Option.Id == optionId && (new string[] { "Dropdown", "Checkbox", "Radiobutton" }).Contains(x.Option.OptionType.Name)
                                                select x.Option;

            var distinctOptions = options.Select(x => new { Id = x.Id, Name = x.Code + "-" + x.Name }).Distinct();

            IEnumerable<OptionRecord> returnOptions = distinctOptions.Select(x => new OptionRecord { Id = x.Id, Name = x.Name });

            return returnOptions.Distinct();
        }

When the Create method calls this function, the result of options is an IEnumerable of 3 OptionRecord objects. When the Update method calls this function with exact same integer values being passed in, the result of options is an IEnumerable of 3 objects, but those objects are NULL instead of being OptionRecord objects.

For the life of me, I cannot understand why this is happening. As long as the same parameter values are being passed into this method, shouldn't the result be the same?

If anyone has any ideas on why this might be occurring, I would appreciate the insight.

Thanks so much!

Coordinator
Sep 22, 2012 at 6:18 PM
Edited Sep 22, 2012 at 6:21 PM

Are you doing anything else in create and update, such as modifying tables?

Sorry, I thought you were in a migration. Did you check that the repository class was the same in both cases?

I'm not sure I understand the multiple step select thing. This may be confusing nHibernate, I don't know. Did you try to simplify the code and have only one Select instead?

Sep 22, 2012 at 6:48 PM

I can try that just to see if it comes back with a result. What will happen without the multiple select though is that I'll get the same record 3 times. The second select was a way to get distinct records. For some reason, just using distinct on the first select didn't actually give me distinct records...it returned all 3 records (of the same kind) that it found.

Let me see what happens if I just do one select and I'll worry about distinct records if I can get it to run. Thanks.

Sep 22, 2012 at 6:58 PM

So...I shortened the method to this

        public IEnumerable<OptionRecord> GetForRule(int reportId, int optionId) {
            IEnumerable<OptionRecord> options = from x in _reportoptionvaluesRepository.Table
                                                where x.Report.Id == reportId && x.Option.Id == optionId && (new string[] { "Dropdown", "Checkbox", "Radiobutton" }).Contains(x.Option.OptionType.Name)
                                                select x.Option;

            return options.Distinct();
        }

It didn't error out this time since the error had actually occurred on the 

var distinctOptions = options.Select(x => new { Id = x.Id, Name = x.Code + "-" + x.Name }).Distinct();

line. BUT...the result that came back is still NULL. So, it's the select for "options" that is returning OptionRecord objects properly when I call this method from Create and NULL objects when I call this method from Update.

The only thing the Update method is doing that the Create method isn't doing, is loading the record to modify and returning it to the View. This is done by calling a Service class to load the record. The Update method looks like this when it loads that record

var optionrule = _optionruleService.Get(optionruleId);
 

Sep 22, 2012 at 7:03 PM

Interesting...I don't actually need the additional select for Distinct anymore. This is code I've been using for a while, so something must have changed where it's actually working pulling back Distinct records on the first select. So, I'll keep that shortened code in there now since it's working.

Still have the issue with the NULL objects being returned when calling it from Update though.

Sep 22, 2012 at 7:16 PM
Edited Sep 22, 2012 at 7:27 PM

I tried this too...same result

 

        public IEnumerable<OptionRecord> GetForRule(int reportId, int optionId) {
            var reportoptionvalues = from x in _reportoptionvaluesRepository.Table
                                     where x.Report.Id == reportId && x.Option.Id == optionId && (new string[] { "Dropdown", "Checkbox", "Radiobutton" }).Contains(x.Option.OptionType.Name)
                                     select x;

            IEnumerable<OptionRecord> options = reportoptionvalues.Select(x => x.Option).Distinct();

            return options;
        }

also tried removing the last criteria in the where clause in case it was having problems with that...same issue

Coordinator
Sep 22, 2012 at 10:16 PM

Still don't understand why you need two selects in a row.

Sep 23, 2012 at 1:41 AM
Edited Sep 23, 2012 at 1:52 AM

The first time I used this code, the first select (even with a distinct at the end), wasn't returning distinct rows. I needed a 2nd select to get the distinct rows. That doesn't seem to be the case any more though...I have the code like this now and it's returning distinct rows. Perhaps a change in something else I did or changes to nHibernate from when I first wrote this piece of code makes it work now.

 

        public IEnumerable<OptionRecord> GetForRule(int reportId, int optionId) {
            IEnumerable<OptionRecord> options = from x in _reportoptionvaluesRepository.Table
                                                where x.Report.Id == reportId && x.Option.Id == optionId && (new string[] { "Dropdown", "Checkbox", "Radiobutton" }).Contains(x.Option.OptionType.Name)
                                                select x.Option;

            return options.Distinct();
        }

 

are you saying I should reduce it to this?

 

        public IEnumerable GetForRule(int reportId, int optionId) {
            return (from x in _reportoptionvaluesRepository.Table
                    where x.Report.Id == reportId && x.Option.Id == optionId && (new string[] { "Dropdown", "Checkbox", "Radiobutton" }).Contains(x.Option.OptionType.Name)
                    select x.Option).Distinct();
        }

doing it this way doesn't give me distinct records and still doesn't help with the NULL issue when calling it from the Update method.

Sep 23, 2012 at 1:56 AM

It's cool if nobody has any idea why it's exhibiting this kind of behavior...its baffling me, so I don't expect that anyone else has a miracle cure =) I was just hoping there wasn't something totally obvious I wasn't understanding about making a call to a method in a Service file from one method in a Controller vs another.

Coordinator
Sep 23, 2012 at 4:58 AM

yeah, I don't know, sorry.