C# EF5:如何只返回外键?

C# EF5:如何只返回外键?,c#,ef-code-first,entity-framework-5,C#,Ef Code First,Entity Framework 5,我首先在N层应用程序中结合使用EF5代码和WCF 我正在客户端和服务器之间以异步和增量方式加载相关实体。一切都很好,但我想做一些优化 考虑一个虚拟实体汽车,以及一个相关实体车轮: public class Car { public int Id { get; set; } public virtual List<Wheel> Wheels { get; set; } } public class Wheel { public int Id {

我首先在N层应用程序中结合使用EF5代码和WCF

我正在客户端和服务器之间以异步和增量方式加载相关实体。一切都很好,但我想做一些优化

考虑一个虚拟实体
汽车
,以及一个相关实体
车轮

public class Car
{
    public int Id { get; set; }        
    public virtual List<Wheel> Wheels { get; set; }
}

public class Wheel
{
    public int Id { get; set; }        
    public virtual int CarId { get; set; }
}
因此,当web服务知道它需要加载所有
轮子时,它可以通过向查询中添加
.Include(car=>car.Wheel)
来实现,但通常它只返回
轮子ID
中的FK列表,稍后可以检索

EF5能轻松做到这一点吗?如果是,如何更换?

更换

公共虚拟列表控制盘{get;set;}

公共虚拟ICollection控制盘{get;set;}

这样EntityFramework将把它理解为一个延迟加载的子列表,在需要之前不会填充值

通过使用LinqToEntities,您只能将键检索到新列表中,如:

public virtual List<int> WheelIDs
{
   get { return Wheels.Select(_w => _w.Id).ToList(); }
}

我认为这需要启用火星。但是对于这种控制,最好使用像Dapper.NET这样的东西。@BradChristie因为我们在这里讨论EF,我不认为火星会成为一个问题。只能是一个连接字符串参数。关于微型ORM,如Dapper.NET、PetaPoco、Massive和其他:它们可以在这里提供帮助。但是,我们还是在谈论EF,这就是为什么我的答案是关于EF;)谢谢你的回复。很高兴了解ICollection与其他集合类型的区别。我也许能用这个。今天下午我要发布一个版本,但之后我会测试这个场景&如果成功了,就标记为答案。仅供尝试做同样事情的人参考:这个答案的前半部分很有魅力。我不知道EF对ICollection和其他列表类型的不同处理。但是,此处检索“WheelID”FKs的方法无法解决问题,因为在“Wheels”上使用get()访问器将导致EF检索Wheel对象。最后,通过在我的DataContext(来自DbContext)@HiredMind上运行一个查询,我能够使用一些Automapper魔术来实现相同的结果。我想您不理解这里的
ICollection
和EF。此代码将使您能够使用
IQueryable
。反过来,这将在demmand上转换为SQL语法。只有当您实际对集合的项进行itarate或将其转换为不可查询的集合时,才会发生这种情况。如果你做了一个包括(轮子)比它将被急切加载。如果没有,则在需要之前不会加载它们。如果正在加载它们,则是您的代码导致了它们的出现。但是请注意,如果您执行某种类型的
foreach
语句,它们将被加载。
public class Car
{
    public int Id { get; set; }        
    public virtual List<Wheel> Wheels { get; set; }  // Normally empty
    public virtual List<int> WheelIDs { get; set; }  // Normally full
}
public virtual List<int> WheelIDs
{
   get { return Wheels.Select(_w => _w.Id).ToList(); }
}
{
   using(var context = new MyContext())
   {
      // Doing this the wheel collection WON'T GET LOADED
      var cars = context.Cars;
   }

   using(var context = new MyContext())
   {
      // Doing this the wheel collection WILL get loaded
      var cars = context.Cars.Include(_c => _c.Wheels);
   }

   using(var context = new MyContext())
   {
      // Doing this also gets the wheel collection loaded
      // But this time, it will retrieve wheel-by-wheel on each loop.
      var cars = context.Cars;
      foreach(var car in cars)
      {
         foreach(var wheel in wheels)
         { /* do something */ }
      }
   }

   using (var context = new MyContext())
   {
      // Doing this will get your id's without loading the entire wheel collection
      var cars = context.Cars;
      var wheelsIDs = cars.Wheels.Select(_w => _w.Id).ToList();
   }

   using (var context = new MyContext())
   {
      // Doing this will return every wheel for your car.
      // This improves performance over the other that retrieves wheel-by-wheel.
      var cars = context.Cars;
      foreach(var car in cars)
      {
         var wheels = car.Wheels.ToList();
      }
   }
}