实体框架,代码优先。调用时不会填充子对象

时间:2014-06-01 12:01:39

标签: c# entity-framework ef-code-first

我首先要掌握EF代码。当我在代码中调用它时,我的域模型设计似乎不支持对象的自动“填充”子项。

型号:

public class Car
{
    [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required,MaxLength(10)]
    public string Registration { get; set; }

    [MaxLength(30)]
    public string Make { get; set; }

    [MaxLength(45)]
    public string Model { get; set; }

    [Required]
    public Coordinates Coordinates { get; set; }

    [Required]
    public Client Client { get; set; }                    
}

public class Coordinates
{
    [Key, ForeignKey("Car")]
    public int Id { get; set; }

    public double Latitude { get; set; }

    public double Longitude { get; set; }

    [Required]
    public Car Car { get; set; }
}

例如,我只是致电:

public List<Car> Get()
{            
    var cars = _context.Cars.ToList();
    return cars;
}

我的对象包含数据库中的所有Cars,但不包含Coordinates。数据库种子正确地创建了数据,但我无法让EF自动引用CoordinatesClient。但我怀疑一旦我们解决了一个问题,它就会解决另一个问题。

我做错了什么,我误解了怎么做?

2 个答案:

答案 0 :(得分:26)

您有几个选择:

  • 通过告诉EF Include()来急切加载相关实体。例如,您可以加载Cars,包括他们的CoordinatesClients,如下所示:

    public List<Car> Get()
    {            
        var cars = _context.Cars
            .Include(car => car.Coordinates)
            .Include(car => car.Client)
            .ToList();
        return cars;
    }
    
  • 通过声明导航属性virtual来延迟加载相关实体,从而告诉EF在首次访问时加载它们。确保您没有为您的上下文禁用延迟加载,如下所示:

    this.Configuration.LazyLoadingEnabled = false;

一个简短的例子如下:

public class Car
{
    // ... the other properties like in your class definition above

    public virtual Coordinates Coordinates { get; set;}
}

public void Get()
{
    var cars = _context.Cars.ToList();
    var coordinates = cars.First().Coordinates; // EF loads the Coordinates of the first car NOW!
}
  • 将相关实体显式加载到上下文中。然后,上下文将为您填充导航属性。看起来像这样:

    public List<Car> Get()
    {
        // get all cars
        var cars = _context.Cars.ToList();
    
        // get all coordinates: the context will populate the Coordinates 
        // property on the cars loaded above
        var coordinates = _context.Coordinates.ToList();
        return cars;
    }
    

答案 1 :(得分:3)

您没有Coordinates的原因是因为它未包含在查询中。有多种方法可以将其包含在结果中:

  1. _context.Cars.Include(car => car.Coordinates).ToList(); ---它会在一次查询中获取带坐标的汽车
  2. 如果您不需要Coordinates所有汽车,您可以执行以下操作:将Coordinates属性设为虚拟,然后当您获得汽车时,您可以获得{{1}如果需要,仅为它们的子集,并且对每个属性“get”访问将对数据库进行单独调用。您还将在调试器中看到EF为您创建了动态类,因此您必须将其设为Coordinates
    有关详细信息,另请参阅this answer