首页 > 解决方案 > 如何使用实体框架查询外键对象?

问题描述

我正在尝试了解 Entity Framework 6,但遇到了一个问题,我已经能够在测试项目中重现该问题:

AMovie有一个Name和一个Revenue。ARevenue有一个GrossIncome

public class Movie
{
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public Revenue Revenue { get; set; }
}

public class Revenue
{
        [Key]
        public int Id { get; set; }
        public double GrossIncome { get; set; }
}

我正在尝试使用 EF6 代码优先在数据库中保留一些有关电影的数据:

public class MovieContext: DbContext
{
    public MovieContext(): base("name=testDB") { }
    public DbSet<Movie> Movies { get; set; }
    public DbSet<Revenue> Revenues { get; set; }
}

我首先在数据库中插入一部新电影及其相关收入:

using (var context = new MovieContext())
{
    Revenue revenue = new Revenue()
                {
                    GrossIncome = 10
                };
    Movie movie = new Movie()
                {
                    Name = "foo",
                    Revenue = revenue
                };

    context.Movies.Add(movie);
    context.SaveChanges();
}

我可以在 SQL Server 中看到创建了表,并且创建了一个Movies.Revenue_Id列,与Revenue.Id.

如果我尝试使用 SQL 查询它,它工作正常:

SELECT Movies.Name, Revenues.GrossIncome
FROM Movies
LEFT JOIN Revenues ON Movies.Revenue_Id = Revenues.Id

返回

Name    GrossIncome
----------------------
foo         10

但是,如果我尝试使用实体框架来查询数据:

using (var context = new MovieContext())
{
    List<Movie> movieList = context.Movies.ToList();
    Console.WriteLine("Movie Name: " + movieList[0].Name);

    if (movieList[0].Revenue == null)
    {
        Console.WriteLine("Revenue is null!");
    }
    else
    {
        Console.WriteLine(movieList[0].Revenue.GrossIncome);
    }

    Console.ReadLine();
}

控制台显示:

Movie Name: foo     <- It shows that the query works, and that the data in the main table is fetched.
Revenue is null!    <- Even though the data in the DB is correct, EF does not read the data from the foreign key.

我的问题很简单:我做错了什么?应该如何读取外键值?

标签: c#sql-serverentity-frameworkentity-framework-6

解决方案


只需包含您要加载的子实体:

using (var context = new MovieContext())
{
    List<Movie> movieList = context.Movies
                                   .Include(m => m.Revenue)   // ADD THIS INCLUDE
                                   .ToList();
    Console.WriteLine("Movie Name: " + movieList[0].Name);

    if (movieList[0].Revenue == null)
    {
        Console.WriteLine("Revenue is null!");
    }
    else
    {
        Console.WriteLine(movieList[0].Revenue.GrossIncome);
    }

    Console.ReadLine();
}

这将加载电影 - 并确保所有对其各自.Revenue引用的引用也已加载。


推荐阅读