我正在评估从EF6升级到EFCore 3.1的过程,并且陷入了简单的左外部联接中。我们有大量的代码,例如以下“
IQueryable<SearchItemResponseDataModel> items = from item in db.Item
from e in db.Ingredient.Where(a => item.ItemId == a.ItemId).DefaultIfEmpty()
select new SearchItemResponseDataModel
{
ItemId = item.ItemId,
Name = item.Name,
IsActive = item.IsActive,
Description = item.Description,
Color = e.Color
};
在EF6中工作正常;但是,在EFCore中,我收到以下异常:
系统的方法'System.Linq.IQueryable 1[Dal.Ingredient]' cannot be used for parameter of type 'Microsoft.EntityFrameworkCore.DbSet
1 [Dal.Ingredient]'的类型为'Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 1[Dal.Ingredient] Where[Ingredient](Microsoft.EntityFrameworkCore.DbSet
1 [Dal.Ingredient]'的表达式。 Linq.Expressions.Expression 1[System.Func
2 [Dal.Ingredient,System.Boolean]])'
如果我像下面这样重写它,它将运行没有问题:
IQueryable<SearchItemResponseDataModel> items = from item in db.Item
join e in db.Ingredient on item.ItemId equals e.ItemId into ef
from e in ef.DefaultIfEmpty()
select new SearchItemResponseDataModel
{
ItemId = item.ItemId,
Name = item.Name,
IsActive = item.IsActive,
Description = item.Description,
Color = e.Color
};
所以,这似乎是由于System.Linq和Microsoft.EntityFrameworkCore之间的命名空间冲突引起的。
我添加了
public static class DbSetExtensions
{
public static IAsyncEnumerable<TEntity> AsAsyncEnumerable<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj) where TEntity : class
{
return Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable(obj);
}
public static IQueryable<TEntity> Where<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj, System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return System.Linq.Queryable.Where(obj, predicate);
}
}
根据这里的建议,进入我班级的基础:https://github.com/dotnet/efcore/issues/18220
如果我删除此替代项,则该方法有效:
IQueryable<SearchItemResponseDataModel> items = from item in db.Item.AsQueryable()
from e in db.Ingredient.AsQueryable().Where(a => item.ItemId == a.ItemId).DefaultIfEmpty()
select new SearchItemResponseDataModel
{
ItemId = item.ItemId,
Name = item.Name,
IsActive = item.IsActive,
Description = item.Description,
Color = e.Color
};
最好有一个覆盖,所以我不需要到处都添加.AsQueryable():(