C#学习教程:无法将类型'System.Linq.IQueryable'隐式转换为'System.Data.Entity.DbSet'Entity.DbSet'我是Linq的新手,所以我在下面有这些案例。现在编译时出现以下错误,提示无法将类型“System.Linq.IQueryable”隐式转换为“System.Data.Entity.DbSet”。varquery=_db.Products;if(bool){query=query.Where(p=>p.Id==id);所以我尝试将var更改为IQueryable并且它起作用了。IQueryable查询=_db.Products;if(bool){query=query.Where(p=>p.Id==id);但是后来,我尝试再次更改它(见下文)并且成功了。varquery=fromproductinproducts选择产品;if(bool){query=query.Where(p=>p.Id==id);我只是想知道为什么另一个有效而另一个无效。一个很好的例子可能会有所帮助。谢谢第一种情况不起作用的原因是System.Linq.IQueryable是由System.Data.Entity.DbSet类实现的接口。在C#中,如果类C实现了接口I,那么当涉及到类型之间的转换时,您也可以将I视为C的基类(即使是语义类C:我推荐这种方法)。并且由于您不能隐式地(即不冗长地)将一个类(或接口)强制转换为其子类之一,因此您将在尝试这样做时遇到编译时错误。你可以做相反的事情,即将一个后代类隐式转换为它的基类(或接口)。这正是第二种情况发生的情况。在您的情况下,您可以使用显式强制转换来欺骗编译器:query=(DbSet)query.Where(p=>p.Id==id);但我强烈建议您不要这样做,因为您最终会遇到令人困惑的异常,因为query.Where(p=>p.Id==id)的结果实际上并不是DbSet的实例,而是代表在DbSet上执行的查询,它实现了IQueryable接口。总而言之,让我们来看看所有场景:场景1://queryisoftypeDbSetvarquery=_db.Products;if(bool){//这里你试图分配一个IQueryable类型的值//给它的后代类型DbSet的变量//因此编译时错误query=query.Where(p=>p.Id==编号);}场景2://这里你隐式地将DbSet类型的值//转换为IQueryable,这是OK的IQueryablequery=_db.Products;if(bool){//这里你分配一个IQueryable类型的值给一个相同类型的变量,这也是可以的query=query.Where(p=>p.Id==id);}场景3://我假设你的代码中有以下行varproducts=_db.Products;//query是IQueryable类型,因为您在DbSet上执行//查询varquery=fromproductinproductsselectproduct;if(bool){//这里你分配一个IQueryable类型的值给一个相同类型的变量,这是可以的query=query.Where(p=>p.Id==id);}使用var,编译器会推估价值右端的表达式类型。当你写varquery=_db.Products;query的类型为DbSet且无法为其分配任何IQueryable,Where扩展方法返回。当您使用查询语法时,查询再次是IQueryable,这使它起作用。这相当于写varquery=products.Select(t=>t);选择扩展方法(如Where)返回IQueryable。这是因为_db.Products不是查询,而是DbSet。第二个块起作用是因为您将它转换为IQueryable,而最后一个块起作用是因为它是一个实际查询。以上是C#学习教程:Cannotimplicitlyconvertthetype'System.Linq.IQueryable'to'System.Data.Entity.DbSet'。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——varquery=_db.Products.Where(x=>true);if(bool){query=query.Where(p=>p.Id==id);}本文收集自网络,不代表任何内容,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
