C# EF5:如何只返回外键?
我首先在N层应用程序中结合使用EF5代码和WCF 我正在客户端和服务器之间以异步和增量方式加载相关实体。一切都很好,但我想做一些优化 考虑一个虚拟实体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 {
汽车
,以及一个相关实体车轮
:
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();
}
}
}