在我将我的项目更新到DotNetCore3.0RC1(可能也在preview9中)之后,我的代码就开始工作了
var value = context.Products.Where(t => t.CategoryId == catId).Select(t => t.Version).DefaultIfEmpty().Max();
开始扔System.InvalidOperationException: Sequence contains no elements
。这张桌子是空的。
如果我添加了ToList()
,所以它看起来像这个DeafultIfEmpty().ToList().Max()
,那么它又开始工作了。无法找到任何有关重大更改的信息。当我跑的时候
var expectedZero = new List<int>().DefaultIfEmpty().Max();
效果很好。这让我觉得EF核心可能出了什么问题。然后,我用完全相同的设置在xUnit中创建了测试,但是测试正在通过(表也是空的,使用InMemoryDatabase而不是活动Server实例)。
我真的很困惑。相关堆栈跟踪:
System.InvalidOperationException: Sequence contains no elements.
at int lambda_method(Closure, QueryContext, DbDataReader, ResultContext, int[], ResultCoordinator)
at bool Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor+QueryingEnumerable<T>+Enumerator.MoveNext()
at TSource System.Linq.Enumerable.Single<TSource>(IEnumerable<TSource> source)
at TResult Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute<TResult>(Expression query)
at TResult Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute<TResult>(Expression expression)
at TSource System.Linq.Queryable.Max<TSource>(IQueryable<TSource> source)
at ... (my method that run the code)
编辑
产品类别:
[Table("tmpExtProduct", Schema = "ext")]
public partial class Product
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Version { get; set; }
[Column(TypeName = "datetime")]
public DateTime ImportDate { get; set; }
public int CategoryId { get; set; }
public string Description { get; set; }
[ForeignKey(nameof(Ext.Category))]
public int CategoryId { get; set; }
[InverseProperty(nameof(Ext.Category.Products))]
public virtual Category Category { get; set; }
}
第二次编辑由ef核生成的 Sql
exec sp_executesql N'SELECT MAX([t0].[Version])
FROM (
SELECT NULL AS [empty]
) AS [empty]
LEFT JOIN (
SELECT [p].[Version], [p].[CategoryId], [p].[ImportDate], [p].[Description]
FROM [ext].[tmpExtProduct] AS [p]
WHERE (([p].[CategoryId] = @__categoryId_0) AND @__categoryId_0 IS NOT NULL)
) AS [t0] ON 1 = 1',N'@__categoryId_0 int',@__categoryId_0=5
发布于 2019-09-25 05:05:38
于是我打开EF核心回购中的问题,得到了答案。显然,这是目前的行为,这可能会改变以后。
建议采用以下方法
var valueFail = context.Products.Where(t => t.CategoryId == catId)
.GroupBy(e => 1)
.Select(t => t.Max(e => e.Version))
.ToList()[0];
这比我的解决方案DeafultIfEmpty().ToList().Max()
更好,因为它将执行所有的工作服务器端,而我的解决方案将在客户机上计算Max()。
发布于 2022-06-09 03:56:21
一个解决办法可能是使用OrderBy
和FirstOrDefault
组合。
var value = context.Products
.Where(t => t.CategoryId == catId)
.OrderByDescending(t => t.Version)
.Select(t => t.Version)
.FirstOrDefault();
我通常使用这种方法,很少使用Max()
。
发布于 2022-06-09 02:49:47
通过米基自答,异常仍然会被抛出,但是这个异常消息变成了"Nullable对象必须有一个值“。因为当序列为空时返回为null,但不能将null分配给值类型int
。
正确的做法是将目标值类型转换为Nullable<>
,它将返回null,而不是抛出“序列不包含任何元素”。或者"Nullable对象必须有一个值“。当序列为空时出现异常。
var value = context.Products
.Where(t => t.CategoryId == catId)
.Select(t => (int?)t.Version)
.Max();
现在,变量value
的类型是Nullable<int>
,请记住检查它是否为空。
https://stackoverflow.com/questions/58039509
复制相似问题