Как использовать несколько моделей в одном представлении для ASP.NET MVC? - PullRequest
7 голосов
/ 29 апреля 2011

Я читал похожие вопросы по SO, но, похоже, не могу решить эту проблему, которая характерна для объектов DBContext (я думаю).Вот некоторый фиктивный код для иллюстрации.

У меня есть следующий код в моем действии Index ():

    public ActionResult Index()
    {
        AnimalDBContext db = new AnimalDBContext();

        return View(db.Dogs);
    }

У меня есть следующий код для моих моделей:

    public class Dog
    {
        public int ID { get; set; }
        public string name { get; set; }
        public string breed { get; set; }
    }

    public class AnimalDBContext : DbContext
    {
        public DbSet<Dog> Dogs { get; set; }
    }

На мой взгляд, у меня есть следующее:

@model IEnumerable<AnimalProject.Models.Dog>
    @foreach (var d in Model)
    {
    <h3>@d.name</h3>
    <h2>@d.breed</h2>
    }

Все отлично работает, представление будет перебирать каждую собаку в моей базе данных.Однако у меня есть другой набор данных DBContext из другой таблицы, который я хочу в том же представлении.Я хочу иметь возможность перечислять каждый элемент в базе данных для этой таблицы.

Это то, что я хочу, если вы поймете мой дрейф:

@model IEnumerable<AnimalProject.Models.Dog>
@model IEnumerable<AnimalProject.Models.Cat>
    @foreach (var d in Dog)
    {
    <h3>@d.name</h3>
    <h2>@d.breed</h2>
    }
    @foreach (var c in Cat)
    {
    <h3>@c.name</h3>
    <h2>@c.breed</h2>
    }

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

"Элемент модели, переданный в словарь, имеет тип 'System.Data.Entity.DbSet 1[AnimalProject.Models.Dog]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable 1 [AnimalProject.Models.Cat] '. "

Итак, как я могу использовать в моём представлении несколько моделей, которые обе получают нужные данные из отдельных таблиц в базе данных?

Ответы [ 3 ]

13 голосов
/ 29 апреля 2011

Как насчет создания пользовательского класса модели представления:

public AnimalModel
{
    public IEnumerable<Dog> Dogs { get; set; }
    public IEnumerable<Cat> Cats { get; set; }
} 

Заполните эту модель в Index и передайте ее в представление, которое будет ожидать AnimalModel вместо перечислимых.

Edit:

Заполнение модели:

public ActionResult Index()
{
    using (var db = new AnimalDBContext())
    {
        var model = new AnimalModel 
        {
            Dogs = db.Dogs.ToList(),
            Cats = db.Cats.ToList()
        };

        return View(model);
    }
}

Просмотр (я никогда не использовал Razor, поэтому надеюсь, что это правильно):

@model AnimalProject.Models.AnimalModel
@foreach (var d in Model.Dogs)
{
  <h3>@d.name</h3>
  <h2>@d.breed</h2>
}
@foreach (var c in Model.Cats)
{
  <h3>@c.name</h3>
  <h2>@c.breed</h2>
}
3 голосов
/ 24 августа 2012

Модель - это просто объект, подобный любому другому объекту в C # (или VB)

Таким образом, вы можете передать любой объект, который хотите, в представление, даже сложные.Если вам нужно представить много вещей, то создайте модель представления (модель только для нужд представления), которая содержит все вещи, которые вы хотите представить, и передайте это представление.Затем из представления вы получаете доступ к отдельным свойствам модели в разных частях представления, чтобы представить их.Примером такого подхода является модель животного, о которой говорил Ладислав Мрнка.Вы помещаете туда перечисляемые собаки и кошки, а затем передаете их на вид.Вы говорите представлению, что ваша модель теперь имеет тип AnimalModel и т. Д. И т. Д. *

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

Контроллер

public ActionResult Index()
{
   return View(new AnimalDBContext()); // We pass a new instance of the dbcontext to the view
}

Просмотр

@model AnimalProject.AnimalDBContext // we declare that our model is of type AnimalDBContext 
@foreach (var d in Model.Dogs) // We reference the dbcontext's sets directly
{
  <h3>@d.name</h3>
  <h2>@d.breed</h2>
}
@foreach (var c in Model.Cats) // We reference the dbcontext's sets directly
{
  <h3>@c.name</h3>
  <h2>@c.breed</h2>
}

Теперь вы объявили, что вашим объектом "Model" будет AnimalDBContext. Таким образом, вы можете получить доступ ко всем свойствам, наборам и т. Д. AnimalDBContext непосредственно из вашего представления.Возможно, это не лучшая абстракция для доступа к данным, но посмотрите, насколько простым стал ваш контроллер!:) Вы просто бросаете весь мир в поле зрения и позволяете ему решать, какие части выбрать и представить ... Конечно, это для простых сценариев.Если вам нужны более сложные вещи, вам в конечном итоге придется вернуться к моделям с пользовательским представлением.

0 голосов
/ 29 апреля 2011

Единственное решение этой проблемы, которое я нашел до сих пор, состоит в том, чтобы забить обе модели в ViewBag, а затем визуализировать частичные виды для деталей, которые используют только одну модель. Конечно, это работает только в том случае, если частичные представления являются отделимыми - как в вашем случае. Это позволяет строго типизировать частичные представления по сравнению с непосредственным доступом к содержимому ViewBag.

Решение похоже на ответ Уфука здесь. Сначала введите данные в ViewBag с контроллера:

ViewBag.Dogs = db.Dogs;
ViewBag.Cats = db.Cats;

Затем визуализируем частичный вид из вида:

@Html.Partial("_ListDogs", ViewBag.Dogs)
@Html.Partial("_ListCats", ViewBag.Cats)

И каждый частичный вид будет выглядеть следующим образом (например, _ListDogs.cshtml):

@model IEnumerable<AnimalProject.Models.Dog>
@foreach (var d in Model)
{
    <h3>@d.name</h3>
    <h2>@d.breed</h2>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...