EF Core启动时偶发System.InvalidOperationException异常排查求助
EF Core启动阶段偶发Sequence contains no matching elements异常
问题现象
使用EF Core将LINQ表达式转换为SQL时,仅在Web应用通过dotnet run刚启动时偶发抛出System.InvalidOperationException,提示Sequence contains no matching elements。异常触发于以下代码段:
var results = await qry .AsNoTracking() .AsSplitQuery() .ToListAsync();
其中qry为IQueryable<Street>类型,调试确认DbContext和DbSet<Street>均不为空且未被释放。预期的LINQ转换逻辑如下:
DbSet<Street>() .Include(p => p.LocalBoard) .ThenInclude(p => p.City) .Where(prop => prop.Name.ToLower().Contains(string.IsNullOrEmpty(<>c__DisplayClass1_0.filter.Name) ? prop.Name.ToLower() : <>c__DisplayClass1_0.filter.Name.ToLower()) && prop.LocalBoardID == <>c__DisplayClass1_0.filter.LocalBoardID != null ? <>c__DisplayClass1_0.filter.LocalBoardID.Value : prop.LocalBoardID ) .Where(r => r.DeleteDate == null) .Select(r => r) .OrderBy(p => p.Name)
未使用.Single()、.First()这类会触发序列匹配的方法,异常仅在启动阶段偶发,当前环境为.NET 7.0 + EF Core 7.0.11。
补充信息
完整查询代码
var qry = context.Street .Include(p => p.LocalBoard) .ThenInclude(p => p.City) .Where(prop => prop.Name.ToLower().Contains(String.IsNullOrEmpty(filter.Name) ? prop.Name.ToLower() : filter.Name.ToLower()) && prop.LocalBoardID == (filter.LocalBoardID != null ? filter.LocalBoardID.Value : prop.LocalBoardID) ) .Where(r => r.DeleteDate == null) .Select(r => r) .OrderBy(p => p.Name) .AsNoTracking() .AsSplitQuery() .ToListAsync();
完整异常堆栈跟踪
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll: 'Sequence contains no matching element' at System.Linq.ThrowHelper.ThrowNoMatchException() at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate) at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression..ctor(IEntityType entityType, ISqlExpressionFactory sqlExpressionFactory) at Microsoft.EntityFrameworkCore.Query.SqlExpressionFactory.Select(IEntityType entityType) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.CreateShapedQueryExpression(IEntityType entityType) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression) at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerQueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query) at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken) at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator() at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.<ToListAsync>d__65`1.MoveNext() at MyProject_api.Domain.Services.ApiLogic.Sequential.MSSQL.ActiveDatabase.Core.RServiceCore`3.<GetAsync>d__18.MoveNext() in E:\Goran\Development\MyProject\MyProject-api\Domain\Services\ApiLogic\Sequential\MSSQL\ActiveDatabase\Core\RServiceCore.cs:line 194
实体类定义
Street类
[Table("Street")] public class Street { [Key] public int ID { get; set; } [Required] [MaxLength(124)] public string Name { get; set; } [Required] public int LocalBoardID { get; set; } [ForeignKey("LocalBoardID")] public virtual LocalBoard LocalBoard { get; set; } [Required] public int UserID { get; set; } [ForeignKey("UserID")] public virtual User User { get; set; } public DateTime? DeleteDate { get; set; } [JsonIgnore] public virtual ICollection<Person> People { get; set; } }
LocalBoard类
[Table("LocalBoard")] public class LocalBoard { [Key] public int ID { get; set; } [Required] [MaxLength(250)] public string Name { get; set; } [Required] [MaxLength(10)] public string IdentificationNumber { get; set; } [Required] public int CityID { get; set; } [ForeignKey("CityID")] public virtual City City { get; set; } [Required] public int UserID { get; set; } [ForeignKey("UserID")] public virtual User User { get; set; } public DateTime? DeleteDate { get; set; } [JsonIgnore] public virtual ICollection<Person> People { get; set; } [JsonIgnore] public virtual ICollection<Street> Streets { get; set; } }
City类
[Table("City")] public class City { [Key] public int ID { get; set; } [Required] [MaxLength(250)] public string Name { get; set; } [Required] [MaxLength(8)] public string PostCode { get; set; } [Required] public int UserID { get; set; } [ForeignKey("UserID")] public virtual User User { get; set; } public DateTime? DeleteDate { get; set; } [JsonIgnore] public virtual ICollection<LocalBoard> LocalBoards { get; set; } [JsonIgnore] public virtual ICollection<Person> People { get; set; } }
排查与解决方向
- 元数据加载竞争:从堆栈看,异常发生在EF Core构建
SelectExpression时调用Enumerable.First找不到匹配元素,大概率是启动阶段模型元数据未完全加载就执行查询导致。可在应用启动时提前初始化DbContext并预热模型,比如在Program.cs中添加await context.Database.EnsureCreatedAsync()或触发一次空查询。 - LINQ表达式优化:原查询条件存在语法歧义,比如
prop.LocalBoardID == (filter.LocalBoardID != null ? filter.LocalBoardID.Value : prop.LocalBoardID),可重构为更简洁的逻辑,避免EF Core解析异常:.Where(prop => (string.IsNullOrEmpty(filter.Name) || prop.Name.ToLower().Contains(filter.Name.ToLower())) && (filter.LocalBoardID == null || prop.LocalBoardID == filter.LocalBoardID.Value) ) - 版本bug修复:EF Core 7.0.11存在启动阶段查询编译的已知竞争问题,升级到.NET 7最新补丁版本(如7.0.15)或直接升级到.NET 8可修复此类偶发问题。
- DbContext生命周期检查:若启动阶段存在多个DbContext实例并行操作,可能导致元数据缓存冲突,需确保DbContext使用Scoped生命周期,避免启动时创建多个并行实例。
内容的提问来源于stack exchange,提问作者Goran Petrović
相关产品推荐
相关产品推荐

