Проблеми при актуализиране на моделен обект на NHibernate със съдържанието на DropDownList

Нов съм в NHibernate, но разбирам по-добре EF4.

Имам основна страница „Редактиране на елемент“ и при изпращане искам да актуализирам обекта си за артикул със стойности от формуляра. FWIW, използвам FormView и използвам новите функции за обвързване на модели на WebForms, където е практично.

Моят обект "Item" има свойство:

public virtual Category Category { get; set; }

което съответства на FK връзка в базата данни (колона „CategoryId“, сочеща към таблица „Категория“.)

Така че моята форма има падащо меню „Категория“. Това падащо меню е заредено със списък на всички обекти на категорията.

При изпращане всичко, което искам да направя, е да присвоя избраната стойност в падащото меню Category на свойството Category на моя обект Item. Доста право напред, нали? :)

Въпреки това срещнах затруднения:

  • Мога лесно да получа падащото меню.SelectedValue, но не мога да присвоя това на моя обект Item. В EF4 моят обект Item ще използва Асоциация на чужд ключ и следователно ще има както свойства Category, така и CategoryId, които автоматично ще се поддържат в синхрон. Когато опитах нещо подобно в NHibernate, получих Невалиден индекс за тази SqlParameterCollection грешка поради опит за многократно използване на една колона.

  • Лесно получавам падащото меню.SelectedItem, но това е от тип ListItem, който не може да бъде прехвърлен към Category.

  • Опитах се да използвам свойството dropdown.DataSource (може би достъп до елемента "SelectedIndex-th"), но при преминаване през кода тази стойност на DataSource беше нулева.

Най-доброто ми (ужасно) решение досега е следното:

var dropdown = (DropDownList)MyFormView.FindControl("dropdown");
var id = dropdown.SelectedValue;
var category = new MyRepository().GetCategoryById(id);
item.Category = category;

Така че правя допълнително извикване на хранилище и получавам отново целия обект Category, когато всичко, което наистина искам да направя, е:

item.CategoryId = id;

Как трябва да правя това?


person Merenzo    schedule 08.11.2012    source източник


Отговори (2)


Използвайте Session.Load когато знаете идентификатора, за да избегнете пътуване до базата данни. Load ще създаде динамичен прокси и ще позволи на елемента да бъде запазен с правилния CategoryId. Зареждането е най-доброто решение в приложения без състояние.

var dropdown = (DropDownList)MyFormView.FindControl("dropdown");
var id = dropdown.SelectedValue; // may need to cast to int
item.Category = session.Load<Category>(id);
person Jamie Ide    schedule 08.11.2012
comment
Благодаря, Джейми #2: този подход е подобен на това, което вече имам, въпреки че сега (отчасти :) разбирам разликите между Get и Load. В моята ситуация (със сесия на заявка) няма стойности на категория в текущата сесия по време на обратното изпращане. Така че все още прави удар в базата данни, за да извлече пълния обект Category, когато всичко, което искам да направя, е да задам CategoryId (който вече имам) на обекта item. - person Merenzo; 12.11.2012
comment
Зареждането трябва да направи това. Виждам обаче в собствения си код, че понякога все още удря базата данни. Има две причини, които знам дали кога това ще се случи: отложеното зареждане е деактивирано или има достъп до свойство, различно от id. - person Jamie Ide; 12.11.2012

Не е необходимо да получавате обекта на категорията, можете просто да създадете нов обект на категория и динамично да зададете идентификатора.

var dropdown = (DropDownList)MyFormView.FindControl("dropdown");
var id = dropdown.SelectedValue;
item.Category = new Category { CategoryId = id };
person UnitStack    schedule 08.11.2012
comment
Благодаря, Джейми #1, въпреки че не работи за мен. Първа грешка: обектът препраща към незаписан преходен екземпляр. След това добавих cascade=All към дефиницията на FK в моя HBM. Това даде втора грешка: не може да се вмъкне: [Category#MyID].... NH интерпретира новия ви израз за категория {} като заявка за вмъкване. - person Merenzo; 12.11.2012