实体框架7 - 访问相关实体

时间:2015-10-19 12:33:50

标签: asp.net asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-core

我的问题是在二级关系中访问Web App中的相关实体。没有找到与EF7相关的正确答案。

我们来看下面3个类的样本:一对多 - x - 多对一。

public class Person {
    public int PersonId { get; set; } 
    public string Name { get; set; }

    public virtual ICollection<Buy> Buys { get; set; } = new List<Buy>();
}

public class Buy {
    public int BuyId { get; set; }
    public int PersonId { get; set; }
    public int BookId { get; set; }

    public virtual Person Person { get; set; }
    public virtual Book Book { get; set; }
}

public class Book {
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Buy> Buys { get; set; } = new List<Buy>();
}

有了上下文。

public class MyContext : DbContext {
    public DbSet<Person> People { get; set; }
    public DbSet<Book> Books { get; set; }
    public DbSet<Buy> Buys { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.Entity<Person>()
            .Collection(c => c.Buys).InverseReference(c => c.Person)
            .ForeignKey(c => c.PersonId);

        modelBuilder.Entity<Book>()
            .Collection(i => i.Buys).InverseReference(i => i.Book)
            .ForeignKey(i => i.BookId);
}

人物控制者 - 详情视图。

// _context present in given scope
public IActionResult Details(int? id) {
    var person = _context.People
            .Include(c => c.Buys)
            .Where(c => c.PersonId == id)
            .FirstOrDefault();
}

通过这种配置,我打算能够从Person模型中获取,不仅是购买信息,还包括相关的其他书籍。喜欢跟随View的一部分。

@model <project>.Models.Person
// (...)

@Html.DisplayFor(model => model.PersonId)      // ok - person
@Html.DisplayFor(model => model.PersonName)    // ok - person

@foreach (var item in Model.Buys) {
    @Html.DisplayFor(modeItem => item.BuyId)     // ok - buy
    @Html.DisplayFor(modelItem => item.Book.Name) // null - book
}

我是否需要在流畅的API中编写其他引用代码,或者在实体模型中进一步包含以便能够从人员级别访问项目数据?

2 个答案:

答案 0 :(得分:2)

您应该像Book一样包含Buys。我的意思是:

var person = _context.People
        .Include(c => c.Buys.Select(x => x.Book))
        .Where(c => c.PersonId == id)
        .FirstOrDefault();

但实际上如果您使用MVC,最好创建ViewModel类,其中包含您在特定View上需要的所有数据,而不是在View上使用EF类。

答案 1 :(得分:0)

在EF 7 beta7中,您还可以使用ThenInclude方法包含多个级别:

var person = _context.People
                     .Include(c => c.Buys)
                     .ThenInclude(b=>b.Book)
                     .FirstOrDefault(c => c.PersonId == id);