Таблица с внешним ключом - PullRequest
2 голосов
/ 21 марта 2011

как я могу построить таблицу «заказов», содержащую «IdOrder», «Описание» и «Пользователь»? ... поле «Пользователь» является ссылкой на таблицу «Пользователи», которая имеет «IdUser» и "Название". Я использую репозитории.


У меня есть этот репозиторий:

Repository<Orders> ordersRepo = new OrderRepo<Orders>(unitOfWork.Session);

чтобы вернуть все ордера на просмотр, я просто делаю:

return View(ordersRepo.All());

Но это приведет к чему-то вроде:

IdOrder : 1 - Описание : SomeTest - Пользователь : UserProxy123ih12i3123ih12i3uh123

-

Когда ожидаемый результат был:

IdOrder : 1 - Описание : SomeTest - Пользователь : Thiago.

PS: я не знаю, почему он возвращает это "UserProxy123ih12i3123ih12i3uh123". В Db есть допустимое значение.


Вид:

Показано в foreach (var item in Model).

@item.Description
@item.User //--> If it is @item.User.Name doesn't work.

Что мне нужно сделать, чтобы включить Имя в этот список? Могу ли я сделать запрос, используя LINQ - NHibernate?

Tks.

Ответы [ 3 ]

1 голос
/ 22 марта 2011

Какой тип ORM вы используете?Вы упоминаете «репозитории», но означает ли это LinqToSql, Entity Framework, NHibernate или другие?

Похоже, вы получаете сообщение об ошибке, поскольку поле User не загружается как часть исходного запроса.Вероятно, это сделано для уменьшения размера результирующего набора путем исключения связанных полей из исходного запроса для Orders.

. Существует несколько вариантов решения этой проблемы:

  1. Настройте репозиторий (или контекст, в зависимости от ORM), чтобы включить свойство User в набор результатов.
  2. Явно загрузите свойство User, прежде чем получить к нему доступ.Обратите внимание, что это было бы дополнительным обходом базы данных и не должно выполняться в цикле.

В тех случаях, когда вы знаете, что вам нужна информация User, было бы разумно убедиться, чточто эти данные возвращены из исходного запроса.Если вы используете LinqToSql, взгляните на тип DataLoadOptions .Вы можете использовать этот тип, чтобы указать, какие отношения вы хотите получить с помощью запроса:

var options = new DataLoadOptions();
options.LoadWith<Orders>(o => o.User);

DataContext context = ...;
context.LoadOptions = options;

var query = from o in context.Orders
            select o;

Должны быть аналогичные методы для достижения того же результата независимо от того, какой ORM вы используете.

В NHibernateВы можете сделать следующее:

using (ISession session = SessionFactory.OpenSession())
{
    var orders = session.Get<Order>(someId);
    NHibernateUtil.Initialize(orders.User);
}

Это приведет только к двум отключениям базы данных (независимо от количества возвращенных заказов).Более подробную информацию об этом можно найти здесь .

0 голосов
/ 23 марта 2011

Возможно при доступе к item.User.Name сессия уже закрыта, поэтому NHib не может загрузить соответствующего пользователя из БД.Вы можете создать некоторую модель и инициализировать ее правильными значениями в контроллере.Также вы можете отключить отложенную загрузку для Orders.User в вашем отображении.

Но, возможно, это другая проблема.Что у вас есть при доступе к "@ item.User.Name" из вашего представления?

0 голосов
/ 21 марта 2011

В asp.net MVC внешний ключ не работает так, как вы его используете.Я считаю, что вы должны установить для пользователя переменную, подобную этой:

User user = @item.User;

Или вам иногда нужно загружать ссылку.Я не знаю, почему это так, но по моему опыту, если я ставлю эту строку перед тем, как что-то делать с внешним ключом, она работает

@item.UserReference.load();
...