When I am developing my ASP.Net App, the following error was displayed.
Error CS0266
Cannot convert implicitly a type 'System.Linq.IQueryable' into 'Microsoft.EntityFrameworkCore.Query.IIncludableQueryable' There is an explicit conversion (check if you lack a cast) urlapp12 C:\Users\mjkpt\source\repos\teststage\urlapp12\urlapp12\Controllers\TagsController.cs 37 active
t.Urlid
and Urlid
are both int
.
The code including the error is the following:
//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());
}
The Url
model Url.cs is the following:
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; }
*/
}
}
The Tag
model Tag.cs is the following:
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 add) I have tried Mohsin Mehmood code, and unfortunately other errors occured.
Error CS0266 Cannot cast implicitly Type 'System.Linq.IQueryable' into 'Microsoft.EntityFrameworkCore.DbSet'. There is an explicit cast. (Are you missing cast?) C:\Users\mjkpt\source\repos\teststage\urlapp12\urlapp12\Controllers\TagsController.cs 45 Active
Error CS0266 Cannot cast implicitly Type 'Microsoft.EntityFrameworkCore.Query.IIncludableQueryable' into 'Microsoft.EntityFrameworkCore.DbSet'. There is an explicit cast. (Are you missing cast?) C:\Users\mjkpt\source\repos\teststage\urlapp12\urlapp12\Controllers\TagsController.cs 45 Active
(2018-05-19 18:43 Added)
It worked! Thank you very much user1672994
:It was necessary to make a little change like the following, but it is not a big problem:
(before change (user1672994's idea))
var blogging02Context = _context.Tag.Include(t => t.Blog).Where(t => t.Urlid == Urlid));
(after change)
var blogging02Context = _context.Tag.Include(t => t.Blog).Where(t => t.Urlid == Urlid);
I ran into the same issue. Include produces a new abstraction level on top of IQueryable, called IIncludableQueryable. Your var blogging02Context becomes IIncludeQueryable which is not directly assignable from your Where statement.
Declare your blogging02Context variable as IQueryable<Tag>
instead of var
. It helped in my case.
IQueryable<Tag> blogging02Context = _context.Tag.Include(t => t.Blog);
if (!string.IsNullOrEmpty(Urlid.ToString()))
{
blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}
A couple things could be improved here.
First the answer to the topic question:
None of the previous answers seem to address the fact that while you can't implicitly convert IQueryable into IIncludableQueryable you can do the opposite. Additionally, IIncludableQueryable is only necessary if you intend to follow it with a ThenInclude() to include another entity based on the first included entity. [for example: context.Orders.Include(x => x.Customer).ThenInclude(x => x.BillingAddress)]
With that said, you could rewrite your code as follows:
// 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
// or explicitly types
IQueryable<Tag> blogging02Context = _context.Tag.Include(t => t.Blog);
if (!string.IsNullOrEmpty(Urlid.ToString()))
{
blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}
Which brings me to another issue with the original code... Why does your method take an integer as a parameter for Urlid only to then convert it to a string to check if it is a null or empty string?(see offending code below)
if (!string.IsNullOrEmpty(Urlid.ToString()))
{
blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}
Is it possible for your method to be called without providing a value for Urlid? If so, then your Urlid will automatically be initialized to 0 (zero) which means your string validation will always produce the same result (it is never null or empty). Instead, you could make your Urlid parameter a nullable int like this:
Index(int id, Url blog, int? Urlid)
and just do a simple null check or a HasValue check
if (Urlid != null)
{
blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}
or
if (Urlid.HasValue)
{
blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}
or just check if it is greater than zero assuming your database doesn't allow for a Urlid of less than 1 (starts at 1)
if (Urlid > 0)
{
blogging02Context = blogging02Context.Where(t => t.Urlid == Urlid);
}
The compile time error is correct as at the first line you have defined the var blogging02Context
to _context.Tag.Include(....
; This Include
method returns Microsoft.EntityFrameworkCore.Query.IIncludableQueryable
type. Later, you are adding where
clause on the blogging02Context
which returns System.Linq.IQueryable
.
You can update the code with follows:
However, Another point Urlid
is defined as int
so this statement if (!string.IsNullOrEmpty(Urlid.ToString()))
will never be false; as default value of int
would be 0. and 0.ToString()
will be "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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With