我是新手,Linq因此下面有这些情况.
现在编译过程中出现错误,说 Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Entity.DbSet'.
var query = _db.Products;
if (bool) {
query = query.Where(p => p.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
所以,我试图改变var到IQueryable和它的作品.
IQueryable<Product> query = _db.Products;
if (bool) {
query = query.Where(p => p.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
但后来,我试图再次改变它(见下文)并且它有效.
var query = from product in products
select product;
if (bool) {
query = query.Where(p => p.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么另一个有效,但另一个没有.
一个很好的例子可能有帮助.谢谢
Grx*_*x70 29
第一种情况不起作用的原因System.Linq.IQueryable是System.Data.Entity.DbSet该类是由类实现的接口.在C#中,如果类C实现了接口I,那么当涉及到类型之间的转换时,您也可以将其I视为C基类(即使语义也class C : I提出了这样的方法).并且由于您不能隐式地(即不是冗长地)将类(或接口)强制转换为其后代类之一,因此在尝试执行此操作时会出现编译时错误.你可以做相反的事情,即将后代类隐式地转换为它的基类(或接口).这正是第二种情况中发生的情况.
在您的情况下,您可以通过显式转换欺骗编译器:
query = (DbSet<Customer>) query.Where(p => p.Id == id);
Run Code Online (Sandbox Code Playgroud)
但我强烈建议你不要因为你最终会得到一个混乱的异常,因为结果query.Where(p => p.Id == id)实际上不是一个实例DbSet<Customer>,而是一些代表在a上执行查询的结果的类DbSet<Customer>,它实现了IQueryable接口.
总而言之,让我们来看看所有场景:
场景1:
//query is of type DbSet<Customer>
var query = _db.Products;
if (bool) {
//here you're trying to assign a value of type IQueryable<Customer>
//to a variable of it's descendant type DbSet<Customer>
//hence the compile-time error
query = query.Where(p => p.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
场景2:
//here you implicitly cast value of type DbSet<Customer>
//to IQueryable<Customer>, which is OK
IQueryable<Customer> query = _db.Products;
if (bool) {
//here you're assigning a value of type IQueryable<Customer>
//to a variable of the same type, which is also OK
query = query.Where(p => p.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
场景3:
//I assume you have the following line in your code
var products = _db.Products;
//query is of type IQueryable<Customer>, because you perform
//a query on the DbSet<Product>
var query = from product in products
select product;
if (bool) {
//here you're assigning a value of type IQueryable<Customer>
//to a variable of the same type, which is OK
query = query.Where(p => p.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
使用var编译器时,可以在赋值右侧推断表达式的类型.当你写作
var query = _db.Products;
Run Code Online (Sandbox Code Playgroud)
query是类型的DbSet<Product>,它可以不被分配任何IQueryable<Product>,其中Where扩展方法的回报.
当您使用查询语法时,query再次IQueryable<Product>使用它.这相当于写作
var query = products.Select(t => t);
Run Code Online (Sandbox Code Playgroud)
该Select扩展方法一样Where,返回IQueryable<Product>.
| 归档时间: |
|
| 查看次数: |
31148 次 |
| 最近记录: |