我有一个具有属性的对象,该属性是另一个对象的集合。我想使用LINQ加载集合属性的一个子集。
以下是我尝试这样做的方法:
manager = db.Managers
.Include(m => m.Transactions.Skip((page - 1) * 10).Take(10))
.Where(m => m.Id == id)
.FirstOrDefault();
上面的代码会抛出一个错误
Include路径表达式必须引用在类型上定义的导航属性。使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性。\ r \ n参数名称:路径
在LINQ中执行此操作的正确方法是什么?提前谢谢。
答案 0 :(得分:1)
您不能使用Include执行此操作。 EF根本不知道如何将其转换为SQL。但你可以用子查询做类似的事情。
final String path = "http://localhost:8080/RestEasy-Spring-MVC-Hibernate/";
ICustomerService proxy = null;
@Before
public void beforeClass(){
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(path));
proxy = target.proxy(ICustomerService.class);
}
@Test
public void testCustomerByIdNewAPI() throws Exception{
CustomerType customerType = proxy.getCustomerInfo(1);
System.out.println("----------------------------------------------------");
System.out.println("Name : "+customerType.getName());
System.out.println("Age : "+customerType.getAge());
System.out.println("CustomerId : "+customerType.getCustomerId());
}
这不会返回Manager类的实例。但是应该很容易修改它以满足您的需求。
您还有两个选择:
无论哪种方式,如果你完全关注性能,我会建议你测试所有3种方法,看看哪种方法最快。请告诉我们结果如何!
答案 1 :(得分:0)
有时,将所有内容放在一个查询中的额外复杂性是不值得的。我会把它分成两个单独的查询:
var manager = db.Managers.SingleOrDefault(m => m.Id == id);
var transactions = db.Transactions
.Where(t => t.ManagerId == id)
// .OrderBy(...)
.Skip((page - 1) * 10).Take(10)
.ToList();
请注意,执行此操作后,还可以使用manager.Transactions
来引用那些刚刚加载的事务:只要将加载的实体加载到同一个上下文中,它就会自动链接它们。只需确保禁用延迟加载,以防止EF自动拉入您专门尝试过滤掉的所有其他事务。