无法将类型“System.Linq.IQueryable”隐式转换为“Microsoft.EntityFrameworkCore.Query.IIncludableQueryable”。

12
当我开发ASP.Net应用程序时,出现了以下错误。
错误CS0266
无法将类型'System.Linq.IQueryable'隐式转换为'Microsoft.EntityFrameworkCore.Query.IIncludableQueryable'。存在显式转换(请检查是否缺少强制转换)。urlapp12 C:\Users\mjkpt\source\repos\teststage\urlapp12\urlapp12\Controllers\TagsController.cs 37 active。
以下是错误的截图: The captured screenshot of the error 代码中的Urlid和Urlid都是int类型。
包含错误的代码如下:
        //int id, [Bind("BlogId,Userid,Url,Title")] Blog blog
        // GET: Tags
//        public async Task<IActionResult> Index()
        public async Task<IActionResult> Index(int id, [Bind("Urlid,Userid,UrlStr,Title")] Url blog, int Urlid)
        {
            /*
            return View(await _context.Tag.ToListAsync());
            */
            var blogging02Context = _context.Tag.Include(t => t.Blog);

            if (!string.IsNullOrEmpty(Urlid.ToString()))
            {
                blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
            }

            ViewBag.Urlid = Urlid;
            return View(await blogging02Context.ToListAsync());

//            return View (await _context.Tag.ToListAsync());
        }

Url 模型 Url.cs 如下:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace urlapp12.Models
{
    public partial class Url
    {
        public Url()
        {
            Post = new HashSet<Post>();
        }

        [Key]
        public int Urlid { get; set; }
        public string UserId { get; set; }
        public string UrlStr { get; set; }
        public string Title { get; set; }

        public string CreatedBy { get; set; }
        public string CreatedBy_UserName { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime CreatedAt_UtcDt { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime CreatedAt_LocalDt { get; set; }

        public string LastUpdatedBy { get; set; }
        public string LastUpdatedBy_UserName { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime LastUpdatedAt_UtcDt { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime LastUpdatedAt_LocalDt { get; set; }

        public virtual ICollection<Tag> Tag { get; set; }
        public virtual ICollection<BlogIUDSqlHistory> BlogIUDSqlHistory { get; set; }
        public ICollection<Post> Post { get; set; }
        /*
        public List<Tag> Tag { get; set; }
        public List<Post> Post { get; set; }
        */
    }
}

Tag模型Tag.cs如下:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace urlapp12.Models
{
    public class Tag
    {
        [Key]
        public int TagId { get; set; }
        public int DispOrderNbr { get; set; }
        public string tagItem { get; set; }
        public int Urlid { get; set; }

        public string CreatedBy { get; set; }
        public string CreatedBy_UserName { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime CreatedAt_UtcDt { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime CreatedAt_LocalDt { get; set; }

        public string LastUpdatedBy { get; set; }
        public string LastUpdatedBy_UserName { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime LastUpdatedAt_UtcDt { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
        public DateTime LastUpdatedAt_LocalDt { get; set; }

        [System.ComponentModel.DataAnnotations.Schema.ForeignKey("Urlid")]
        public Url Blog { get; set; }
    }
}

(2018-05-19 18:17 添加) 我尝试了Mohsin Mehmood的代码,但不幸出现了其他错误。

错误 CS0266 无法将类型“System.Linq.IQueryable”隐式转换为类型“Microsoft.EntityFrameworkCore.DbSet”。存在显式转换。(是否缺少强制转换?) C:\Users\mjkpt\source\repos\teststage\urlapp12\urlapp12\Controllers\TagsController.cs 45 活动的

错误 CS0266 无法将类型“Microsoft.EntityFrameworkCore.Query.IIncludableQueryable”隐式转换为类型“Microsoft.EntityFrameworkCore.DbSet”。存在显式转换。(是否缺少强制转换?) C:\Users\mjkpt\source\repos\teststage\urlapp12\urlapp12\Controllers\TagsController.cs 45 活动的

(2018-05-19 18:43 添加)

它奏效了!非常感谢user1672994
:有必要进行一些小更改,如下所示,但这不是一个大问题:

(更改前(user1672994的想法))

var blogging02Context = _context.Tag.Include(t => t.Blog).Where(t => t.Urlid == Urlid));

(更改后)

var blogging02Context = _context.Tag.Include(t => t.Blog).Where(t => t.Urlid == Urlid);
4个回答

28

我遇到了同样的问题。Include 在 IQueryable 上产生了一个新的抽象级别,称为 IIncludableQueryable。你的 var blogging02Context 变成了 IIncludeQueryable,无法直接从 Where 语句中进行赋值。

请将你的 blogging02Context 变量声明为 IQueryable<Tag> 而不是 var。这在我的情况下有所帮助。

        IQueryable<Tag> blogging02Context = _context.Tag.Include(t => t.Blog);

        if (!string.IsNullOrEmpty(Urlid.ToString()))
        {
            blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
        }

2
非常惊讶,显式声明也适用于我...使用显式声明而不是var。 - Ram

9

这里有几个地方可以改进一下。

首先回答一下主题问题:

之前的回答似乎都没有提到一个事实,就是虽然你不能将IQueryable隐式转换为IIncludableQueryable,但你可以做相反的转换。 此外,只有当你想要在第一个包含的实体的基础上包含另一个实体时,才需要使用IIncludableQueryable。[例如:context.Orders.Include(x => x.Customer).ThenInclude(x => x.BillingAddress)]

说完这些,你可以按以下方式重写代码:

// when using var
var blogging02Context = _context.Tag.Include(t => t.Blog).AsQueryable();

if (!string.IsNullOrEmpty(Urlid.ToString()))
{
   blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}

或者
// or explicitly types
IQueryable<Tag> blogging02Context = _context.Tag.Include(t => t.Blog);

if (!string.IsNullOrEmpty(Urlid.ToString()))
{
   blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}

这让我想到了原始代码中的另一个问题... 为什么您的方法以整数形式接收Urlid参数,然后将其转换为字符串以检查它是否为空或空字符串?(请参阅以下有问题的代码)
if (!string.IsNullOrEmpty(Urlid.ToString()))
{
   blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}

您的方法是否可能在不提供Urlid值的情况下进行调用?如果是这样,那么您的Urlid将自动初始化为0(零),这意味着您的字符串验证将始终产生相同的结果(它永远不会为null或空)。 相反,您可以将Urlid参数设置为可空int类型,如下所示:

Index(int id, Url blog, int? Urlid)

只需进行简单的 null 检查或 HasValue 检查

if (Urlid != null)
{
    blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}

或者
if (Urlid.HasValue)
{
   blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}

或者,只需检查它是否大于零,假设您的数据库不允许Urlid小于1(从1开始)

if (Urlid > 0)
{
   blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}

3
编译时出现的错误是正确的,因为在第一行中定义了“var blogging02Context”为“_context.Tag.Include(....”,而这个“Include”方法返回“Microsoft.EntityFrameworkCore.Query.IIncludableQueryable”类型。后来你在“blogging02Context”上添加了“where”子句,它返回“System.Linq.IQueryable”。
你可以按照以下方式更新代码:
然而,另一个问题是“Urlid”被定义为“int”,所以语句“if(!string.IsNullOrEmpty(Urlid.ToString()))”永远不会为false;因为“int”的默认值是0,而“0.ToString()”将是“0”。
    public async Task<IActionResult> Index(int id, 
    [Bind("Urlid,Userid,UrlStr,Title")] Url blog, int Urlid)
    {
        var blogging02Context = _context.Tag.Include(t => t.Blog).Where(t => t.Urlid == Urlid));

        ViewBag.Urlid = Urlid;
        return View(await blogging02Context.ToListAsync());
    }

0

请尝试以下代码:

 var blogging02Context = _context.Tag;

            if (!string.IsNullOrEmpty(Urlid.ToString()))
            {
                blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
            }

            blogging02Context = blogging02Context.Include(t => t.Blog);

            ViewBag.Urlid = Urlid;

如果包含的博客参与到Where子句中,那该怎么办?那时它可能就无法正常工作了。 - thomasgalliker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接