2015-02-08 2 views
2

Моя цель здесь - использовать EF7 с MVC6 [BETA2], чтобы перечислить несколько книжных полок и количество книг на каждой полке.Связности сущностей для EF7 MVC6

Схема базы данных создается правильно с правильными отношениями в таблице. Я могу успешно добавить полки и книги в базу данных, включая отношения с внешним ключом (см. Код ниже).

Когда я проверяю индексную страницу, на которой должна отображаться количество книг на каждой полке, я не получаю никаких данных о количестве книг и ошибок. В Полка Объект собственности Книги остается незаселенным с . Заказывается объектов, поэтому счет равен нулю (см. Код ниже).

В EF7 есть где-нибудь, где мне нужно написать код для заполнения Shelf.Books, или это должно произойти автоматически в EF7?

BookShelf.cs

namespace MyApp.Models 
{ 
    public class Shelf 
    { 
     public int ShelfId { get; set; } 
     public string Name { get; set; } 
     public virtual List<Books> Books { get; set; } 
    } 

    public class Book 
    { 
     public int BookId { get; set; } 
     public string Name { get; set; } 
     public int ShelfId { get; set; } 
     public Shelf Shelf{ get; set; } 
    } 
} 

ApplicationDbContext.cs

namespace MyApp 
{ 
    public class ApplicationDBContext 
    { 
     public DbSet<Shelf> Shelf { get; set; } 
     public DbSet<Book> Book { get; set; } 
    } 

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     builder.Entity<Shelf>().Key(s => s.ShelfId); 
     builder.Entity<Book>().Key(b => b.BookId); 

     builder.Entity<Shelf>()     
      .OneToMany(s => s.Book) 
      .ForeignKey(k => k.ShelfId); 

     base.OnModelCreating(builder); 
    } 
} 

ShelfController.cs

namespace MyApp 
{ 
    private ApplicationDBContext db; 

    public BuildingsController(ApplicationDBContext context) 
    { 
     db = context; 
    } 

    // GET: Shelves 
    public async Task<IActionResult> Index() 
    { 
     return View(await db.Shelves.ToListAsync()); 
    } 
} 

Index.cshtml

... 
@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.Name) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Books.Count) 
     </td> 
    </tr> 
} 
.... 
+0

Возможно, потому что 'db.Shelves.ToListAysnc()' создает список полки, который используется вне области действия контроллера, поэтому 'Books' никогда не заселяется. Во-вторых, если вещи не изменились с 6.1, ваше свойство 'Books' должно действительно быть' ICollection '. Наконец, вы должны создать модель View, которая фактически представляет данные, необходимые для представления, и не полагаться на методы в представлении, чтобы делать логику (например, подсчет, что, скорее всего, почему это не работает). –

+0

Спасибо @ErikPhilips! – Will

+0

'ICollection ' был изменен в EF7 на 'List '. Из ваших комментариев я не уверен, если вы говорите, что он не заполняется, потому что я не использую модель представления или потому, что 'db.Shelves.ToListAsync()' выходит за рамки. Как вы предлагаете изменить его? – Will

ответ

0

Посмотрите на ICollection Vs List in Entity Framework. Я чувствую, что незначительные примеры EF7, использующие List<>, являются лишь некорректными (трудно представить, что с EF7 наилучшая практика изменилась с ICollection<> на List<>, как правило, очень плохой практикой выставлять конкретный тип сбора в качестве имущества.)

за свой комментарий Я хотел бы изменить:

Создание Просмотр моделей

public class IndexViewModel 
{ 
    public IEnumerable<ShelveModel> Shelves { get; set; } 
} 

public class ShelveModel 
{ 
    public string Name { get; set; } 
    public int BookCount { get ; set; } 
} 

Обновление логики

// GET: Shelves 
public async Task<IActionResult> Index() 
{ 
    var model = new IndexViewModel(); 
    model.Shelves = db.Shelves 
     .Select(s => new 
     { 
      Name = s.Name, 
      BookCount = s.Books.Count() 
     }) 
     .ToListAsync() 
     .Select(s => new ShelveModel() 
     { 
      Name = s.Name, 
      BookCount = s.Books.Count() 
     }) 
     .ToList(); 

    return View(model); 
} 
+0

Индекс() дает мне фанк-ошибку 'Необработанное исключение, возникшее при обработке запроса. InvalidOperationException: при вызове из 'VisitMethodCallExpression' выражения типа 'Expression' могут быть заменены другими ненулевыми выражениями типа 'Expression'. Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert [T] (выражение T, String methodName) 'Любые идеи? – Will

+0

Проблема, похоже, связана с 'await' в' shelfIndexViewModel.ShelfModels = await db.Select() '..... так что это, вероятно, вне темы. – Will

+0

Код недоволен отсутствием 'await' внутри функции' async'. – Will

0

Я обнаружил, что EF не заполняет родительский объект связанными дочерними объектами из коробки. Например, myShelf.Books будет пуст до заполнения в функции действия контроллера.

Смежные вопросы